티스토리 뷰

Chatper07. 스프링 폼 태그 : 도서 등록 페이지 만들기

 

 

 

7.1 스프링 폼 태그 개요

동적 웹 애플리케이션에서 가장 중요한 기능은 사용자에게 정보를 입력받아 처리하는 것이다. 이것은 폼이다.

사용자가 입력하거나 선택한 정보를 웹 서버로 전달하는 것은 스프링 폼 태그이다.

 

 

 

7.1.1 스프링 폼 태그

스프링 폼 태그는 스프링 MV와 연동되는 태그 라이브러리이다.

스프링 폼 태그는 폼에서 전달되는 파라미터 이름으로 Setter() 메서드를 작성한 클래스의 프로퍼티(필드 이름)에 접근할 수 있고 컨트롤러가 다루는 데이터를 참조할 수 있어 동작을 더 쉽고 편하게할 수 있다.

 

스프링 폼 태그를 사용할 경우 뷰 페이지 위쪽에 아래와 같은 스프링 폼 태그 라이브러리를 선언해야 한다. 

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

 

prefix="form"은 태그 이름이 form인 라이브러리의 태그를 뷰 페이지의 어느 곳이든 이용한다는 것을 나타낸다.

prefix="form"이므로 스프링 폼 태그는 <form:태그이름> 형식으로 사용한다.

 

이것은 <c:out>과 같은 형식을 가지는데 이것도 prefix="c"를 사용하고 태그를 <c:out>으로 사용한다.

 

 

스프링 폼 태그의 종류

태그 유형 설명 출력되는 HTML 태그
<form> 폼의 시작과 끝을 나타낼 때 사용한다. <form>
<input> 사용자가 일반 텍스트를 입력할 수 있는 입력 필드를 만들 때 사용한다. <input type="text">
<checkbox> 많은 옵션 중 하나를 선택할 때 사용한다. <input type="checkbox">
<chekcboxes> <form:checkbox> 목록을 나타낼 때 사용한다.
<radiobutton> 많은 옵션 중 하나를 선택할 때 사용한다. <input type="radio">
<radiobuttons> <form:radiobutton> 목록을 나타낼 때 사용한다.
<password> 사용자가 텍스트를 입력하면 자동으로 (*)로 변환되어 입력할 때 사용한다. <input type="password">
<select> 콤보 박수나 리스트 박스를 나타낼 때 사용한다. <select>
<option> <select>...</select>에 포함되어 목록을 구성할 때 사용한다. <option>
<options> <form:option>목록을 나타낼 때 사용한다.
<textarea> 사용자가 여러 줄의 텍스트를 입력할 수 있도록 입력 박스를 제공할때 사용한다. <textarea>
<hidden> 웹 브라우저가 출력하지 않는 입력 폼으로 사용한다.
<error> 유효성 검사(Validation)에서 생긴 오류 메시지를 나타낼때 사용한다.  

 

* 스프링 폼 태그는 데이터 변환이 편리하고 쉽다.

 

 

 

 

7.1.2 스프링 폼 태그 사용법

 

 

<form> 태그

<form> 태그는 단독으로 쓰지 않고 사용자에게 데이터를 입력받아 상호 작용하는 다양한 입력 양식과 관련된 내용을 포함하는 최상위 태그로 사용한다.

<form:form 속성1="값1" [속성2="값2" ...]>
	//다양한 입력 양식 태그(<input>, <select>, <textarea>)
</form:form>

 

 

 

<form> 태그의 속성

속성 설명
modelAttrivute(또는 commandName) 참조하는 커맨드 객체를 설정한다. 반드시 첫 글자는 소문자여야 한다.
action 데이터를 받아 처리하는 웹 페이지의 URL을 설정한다.
method 데이터가 전송되는 HTTP 방식을 설정한다.
name 폼을 식별하는 이름을 설정한다.
target 폼 처리 겨과의 응답을 실행할 프레임을 설정한다.
enctype 폼을 전송하는 콘텐츠 MIME 유형을 설정한다.
accept-charset 폼을 전송에 사용할 문자 인코딩을 설정한다.

 

 

<form>태그는 HTML의 <form>태그와 다르게 modelAttribute 속성을 지원하여 <input>이나 <hidden>같은 태그들이 커맨드 객체의 프로퍼티(필드 이름)에 접근할 수 있게 한다. (=DTO의 변수에 접근)

이 말은 즉 객체를 만들어 지원하기 때문에 get을 하지 않아도 된다는 뜻과 같다.

 

<form:form modelAttribute="member">
	...
</form:form>

 

위의 코드에서 modelAttribute = "member"는 member라는 객체를 참조한다. 

참조하는 객체인 member가 만들어지는데 이것은 클래스 안에 존재해야만 한다.

 

* action url 속성을 지정하지 않으면 method는 post로 설정되고 action 속성은 현재 요청 url이 된다.

 

 

 

 

 

<form> 안에 사용하는 태그

스프링 폼 태그들은 <form:form> 태그 내 중첩되어 사용되며 반드시 종료(/>)태그로 닫아야 한다.

<form:form> 태그 내 modelAttribute 속성을 설정하면 중첩되는 <form:form> 태그에 반드시 path 속성을 설정해야 한다.

그렇지 않으면 커맨드 객체의 필드에 접근할 수 없다.

 

 

<form:form modelAttribute="커맨드 객체">
	<form:태그 이름 path="커맨드 객체의 프로퍼티(필드)" />
</form:form>

 

 

* path : 자바 클래스의 변수

아래의 코드에서 <form:input path="id" name="id"/>를 예시로 보면 modelAttribute가 member이니까

member 객체의 id(path)로 간다는 뜻이다.

 

* action해야 url 발생함. 아니면 현재 url로 표기된다.

 

 

 

 

webapge07_01.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>    
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Form Tag</title>
</head>
<body>
	<h3>회원가입</h3>
	<form:form modelAttribute="member" method="post">
		<p>아이디 : <form:input path="id" name="id" />
		<p>비밀번호 : <form:password path="password" />
		<p>거주지 : <form:select path="city" >
			<form:option value="서울시">서울시</form:option>
			<form:option value="경기도">경기도</form:option>
			<form:option value="인천시">인천시</form:option>
			<form:option value="충청도">충청도</form:option>
			<form:option value="전라도">전라도</form:option>
			<form:option value="경상도">경상도</form:option>
			</form:select>
		<p>성별 : <form:radiobutton path="sex" value="남성" />남성
			<form:radiobutton path="sex" value="여성" />여성
		<p>취미 : 독서<form:checkbox path="hobby" value="독서" />
			운동<form:checkbox path="hobby" value="운동" />
			영화<form:checkbox path="hobby" value="영화" />
		<p><input type="submit" value="가입하기"/>
			<input type="reset" value="다시쓰기"/>	
	</form:form>
</body>
</html>

 

 

 

아래는 member라는 객체를 가지고 있는 클래스이다.

변수들을 선언한 것을 보면 hobby는 배열 형태를 가지는데

체크박스는 여러개 값을 가질 수 있기 때문에 데이터 타입으로 배열을 가진다.

 

 

Member.java

package com.springmvc.chap07;

import java.util.Date;

public class Member {
	private int id;
	private String password;
	private String city;
	private String sex;
	private String[] hobby;
	private Date birth;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
            ....
	
	
}

 

 

 

 

Example01Controller.java

package com.springmvc.chap07;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class Example01Controller {
	
	@GetMapping("/member")
	public String showForm(Model model) {
		Member member = new Member();
		System.out.println("@GetMapping-----------------");
		System.out.println("아이디 : " +member.getId());
		System.out.println("비밀번호 : " +member.getPassword());
		System.out.println("거주지 : " +member.getCity());
		System.out.println("성 별 : " +member.getSex());
		System.out.println("취 미 : " +member.getHobby());
		model.addAttribute("member",member);
		return "webpage07_01";
	}
}

 

 

 

아래부터는 출력 결과이다.

url 주소창을 보면 입력시의 주소창과 제출 후의 주소창의 url이 같은 것을 볼 수 있다.

이것은 action 속성을 지정하지 않았기 때문에 원래의 url를 그대로 사용한 것임을 알 수 있다.

 

 

위의 코드를 보면 GetMapping에 method=post 방식을 사용했기 떄문에 아래와 같은 오류 페이지가 뜬다.

 

콘솔창에 출력된 결과를 보면 아래와 같이 나오는데 분명 값을 입력했지만 null로 나온것을 볼 수 있다.

이것의 이유는 코드 작성시 GetMapping을 사용했기 때문이다.

Get은 view 페이지만 제공하고 데이터 등록은 제공하지 않기 때문이다.

출력되는 것을 보고자 한다면 Post를 사용해야한다.

Post는 View 페이지를 제공하고 동시에 데이터 등록도 제공한다.

 

 

 

 

 


 

 

7.2 @ModelAttribute를 이용한 데이터 바인딩

 @ModelAttribute 애너테이션은 웹 요청 url을 처리하는 요청 처리 메서드가 호출되기 전에 커맨드 객체에 데이터를 미리 담는다.

 

 

데이터 바인딩이란?
데이터 바인딩이란 웹 페이지에서 전달되는 요청 파라미터 값을 동적으로 도메인 객체의 프로퍼티에 설정해 주는 것이다.
문자열로 전달된 파라미터는 도메인 객체의 프로퍼티 타입(int, boolean, char 등)에 맞게 변환해야 한다. 이렇게 사용자가 입력한 문자열 값을 프로퍼티 타입에 맞춰 자동으로 변환해 할당하는 것을 데이터 바인딩이라고 한다.


바인딩은 자동으로 값을 넣는 것으로 웹 페이지에서 DTO로 값을 넣어준다.

 

 

7.2.1 요청 처리 메서드의 매개변수에 @ModelAttribute 적용

폼 페이지에서 입력된 데이터가 전달되면 @ModelAttribute 는 커맨드 객체에 매핑되어 프로퍼티에 데이터를 채우는 역할을 한다.

@ModelAttribute를 컨트롤러 안의 @RequestMapping이 적용된 요청 처리 메서드의 매개변수로 설정하여 사용한다.

 

@ModelAttribute를 사용하면 폼 페이지에서 입력된 데이터를 자동으로 할당해준다.

또한 요청 처리 메서드의 매개변수인 커맨드 객체 이름도 자유롭게 변경해 사용할 수 있다.

자유롭게 변경하여 사용은 할 수 있지만 이름이 다르기 때문에 어떠한 경로를 가지는지 지정해주어야한다.

 

 

 

 

 

 

Example02Controller.java

 

package com.springmvc.chap07;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class Example02Controller {
	@PostMapping("/member")
	public String submitForm(@ModelAttribute Member member, Model model) {
		System.out.println("@PostMapping-------------");
		System.out.println("아이디 : " +member.getId());
		System.out.println("비밀번호 : " +member.getPassword());
		System.out.println("거주지 : " +member.getCity());
		System.out.println("성 별 : " +member.getSex());
		System.out.println("취 미 : ");
		for(int i=0; i<member.getHobby().length; i++) {
			System.out.print("["+member.getHobby()[i]+ "]");
		}
		model.addAttribute("member",member);
		return "webpage07_02";
	}
}

 

 

 

 

 

webpage07_02.jsp

 

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Form Tag</title>
</head>
<body>
	<h3>회원가입</h3>
	<p> 아이디 : ${member.id }
	<p> 비밀번호 : ${member.password }
	<p> 거주지 : ${member.city }
	<p> 성 별 : ${member.sex }
	<p> 취 미 : <c:forEach items="${member.hobby }" var="hobby">
		[<c:out value="${hobby }"/>]
		</c:forEach>
</body>
</html>

 

 

url을 유심히 봐야한다. 먼저 폼 작성하는 페이지의 주소는 member로 표기되는 것을 볼 수 있다.

 

 

 

 

입력 후 보여지는 창을 보면 이전의 url 주소와 같은 것을 볼 수 있는데

이것의 이유는 코드를 작성했을 때 action을 따로 지정하지 않았기 때문이다.

action을 작성하지 않으면 url은 기존의 것을 그대로 사용한다.

 

@PostMapping 을 사용했으므로 데이터를 등록하고 view페이지를 반환한다.

그러므로 아래와 같이 데이터가 출력된다.

 

 

 

 

 

7.2.2 메서드에 @ModelAttribute 적용

컨트롤러 안에 @RequestMapping 이 적용되지 않은 별도의 일반 메서드를 만들어 해당 메서드에 @ModelAttribute를 적용하는 것을 메서드 수준의 @ModelAttribute라고 한다. (메서드 위에 작성)

 

* 현재 시간, 가입 시간 출력할 때 많이 사용한다.(값을 생성)

 

@ModelAttribute("모델 속성 이름")
public String 메서드 이름(){
	...
}

@ModelAttribute
public void 메서드 이름(Model model){
	//model.addAttribute(...);
}

 

 

 

 

Example03Controller.java

package com.springmvc.chap07;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;

@Controller
public class Example03Controller {
	@GetMapping("/exam03")
	public String showForm() {
		return "webpage07_03";
	}
	
	@ModelAttribute("title")
	public String setTitle() {
		return "@ModelAttribute 유형";
	}
	
	@ModelAttribute
	public void setsubTitle(Model model) {
		model.addAttribute("subtitle","메소드에 @ModelAttribute 애노테이션 적용하기");
	}
}

 

 

webpage07_03.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Form Tag</title>
</head>
<body>
	<h2>${title }</h2>
	<h4>${subtitle}</h4>
</body>
</html>

 

 

 

 

 

* 뷰 리다이렉션

뷰 리다이렉션(view redirection)이란 사용자 웹 요청에 따라 현재 뷰 페이지에서 다른 뷰 페이지로 이동하는 것을 의미한다.

뷰 다이렉션에는 redirect 방식과 forward 방식이 있다.

컨트롤러의 요청 처리 메서드는 기본적으로 GET 방식을 사용하기 때문에 뷰 페이지 읻종 방식은 forward 방식을 따른다.

 

1. redirect 방식

  • 웹 브라우저가 요청 url을 변경하면서 응답 뷰 페이지로 이동하는 방식이다.
  • 웹 브라우저에서 url을 요청하면 응답 뷰 페이지의 url로 이동한다. 이떄 웹 브라우저는 새로운 요청을 생성하여 이동할 url에 다시 요청한다. 그래서 처음 보냈던 최초 요청 정보는 이동된 url에서는 더는 유효하지 않게 된다. (request객체 사라지기때문에 모델 앤 뷰 사용한다.)
  • 품에서 데이터를 입력받 등록하여 시스템(세션,DB)에 변화가 생기는 요청(로그인, 회원 가입, 글쓰기 등)이 있을 때 사용한다.
  • 외부로 나갔다가 들어온다.
  • 외부로 나갔다가 들어오기 때문에 세션도 없어진다. 그렇기 때문에 쿠키로 저장해놓고 꺼내씀
  • 새로 시작하는 것과 같다. url 주소가 서버/프로젝트/ 이 후로 생성됨 (url새로 생성)

 

2. forward 방식

  • 웹 브라우저가 최초 요청한 url을 유지하면서 응답 뷰 페이지를 표현하는 방식이다. (하위로만 이동한다. -> request 유효)
  • 현재 뷰 페이지에서 이동할 url로 요청 정보를 그대로 전달하므로 사용자가 최초로 요청한 요청 정보는 이동된 url에서도 유효하다. 실제로 웹 브라우저는 다른 페이지로 이동했음을 알 수 없다. 따라서 웹 브라우저에는 최초에 호출한 url이 표시되고, 이동한 페이지의 url 정보는 확인할 수 없다.
  • 시스템에 변화가 없는 단순 조회 요청(글 목록 보기, 검색 등)일 때 사용한다.
  • 내부에서 동작한다.
  • url이 이어서 붙인다. 그러므로 상위로 못올라간다.
  • Read 라인은 하위 명령 페이지가 있을 가능성이 높으므로 forward를 사용한다.

 

 

 


 

7.3 @InitBinder를 이용한 커스텀 데이터 바인딩

 

 

 

 

7.3.1 메서드 @InitBinder 적용

 

 

 

 

 

7.3.2 폼 파라미터의 커스텀 데이터 바인딩

 

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday