본문 바로가기
Spring/이론

Spring Web Form

by 모스키토끼 2020. 3. 25.

1. Data Binding

- request parameter들은 어떻게 해당 오브젝트로 옮겨질까

  • Naive solution

    - @RequestParam annotaion을 사용하여 메서드 매개 변수와 bind 해준다.
    ex)
    @RequestMapping("/deget")
    public String doGet( @RequestParam("name") String name){... }
    -> 이런 식으로 받은 매개변수를 객체를 만들어 set 해주는 방식
  • Spring Data Binding

    - form에서 오는 매개변수를 자동으로 객체에 바인딩시켜준다.
    ex)
    @RequestMapping(value="/docreate", method=RequestMethod.POST)
    public String doGet(EmployeeVo ){... }
    -> Spring이 자동적으로 employeeVo객체에 받은 requestParameter를 넣어준다.
    • 바인딩되는 과정
      1. Dispatcher Servlet에서 요청을 받음
      2. 새로운 form bean이 인스턴스화 된다.
      3. form bean은 requestParameter에서 채워진다.
      4. form bean이 모델에 추가된다.
      5. bean을 Controller로 전달
      6. Controller에서 Dispatcher Serlvet에 Model 객체를 전달한다.
      7. Dispatcher Servelt에서 View로 Model 객체를 전달 후 View는 객체를 사용하여 render
    • View 예시
      - <body> hihi, ${employeeVo.name} </body>

2. Data Validation

- 사용자가 잘못된 입력을 한 경우 제대로 된 입력을 위해 안내를 해주어야 한다.
안내 예시) 이메일 형식이 아닙니다.(이메일 형식 예시: aaa@naver.com)

  • Hibernate Validator

    • 사용자의 오류를 감지하려면 form bean에서 캡슐화된 form data의 유효성을 검증해야 한다.
      (쉽게 말해 Bean을 정의한 클래스의 멤버 변수에 대해 유효성 설정이 필요하다는 것)
    • Bean Validation API(JSR-303)는 JavaBean 유효성 검사를 위한 API를 정의한다.
      - @NotNull, @Pattern, @Size annotation을 달아 Bean의 각 속성에 유효성 검사를 할 수 있다.
    • Bean Validation API의 reference 구현인 Hibernate Validator 사용 예시
      - Hibernate Validator는 몇 가지 커스텀 annotation을 제공한다. (예 : @Email)

      - 라이브러리 추가
      <dependency>
      <groupId> org.hibernate </groupId>
      <artifactId> hibernate-validator </artifactId>
      <version>... </version>
      </dependency>
Public class EmployeeVo{
	private int id;
    
    @Size(min=5, max=100)
    @Pattern(regexp="^[A-Z]{1}[a-z]+$")
    private String name;
    
    @NotEmpty
    @Email
    private String email;
    ...
}
  • Message Interpolation

    - 위반된 Bean 유효성 검증 제한 조건에 대한 오류 메시지를 작성하는 프로세스

Message Interpolation 예시

- 위와 같은 결과를 얻기 위해서 각 속성에 message descriptor를 설정

예시

import java.io.Serializable;
 
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
 
public class EmployeeVO implements Serializable 
{
    private static final long serialVersionUID = 1L;
 
    private Integer id;
     
    @Size(min = 3, max = 20)
    private String firstName;
     
    @Size(min = 3, max = 20)
    private String lastName;
     
    @Pattern(regexp=".+@.+\\.[a-z]+")
    private String email;
 
    //Setters and Getters
 
    @Override
    public String toString() {
        return "EmployeeVO [id=" + id + ", firstName=" + firstName
                + ", lastName=" + lastName + ", email=" + email + "]";
    }
}
  • Validating Object

    • 검증은 @Valid annotation을 달면 된다.
    • @Valid는 객체의 유효성 검사를 한 후에 Model에 추가한다.
      ex) @RequestMapping(... )
           public String doGet(@Valid EmployeeVo employeeVo){... }
    • Handler 메서드(@RequestMapping annotation이 달린 메서드)는 검증 프로세스 결과가 담긴 객체인 BindingResult를 요청할 수 있다.
      ex) @RequestMapping(... )
           public String doGet(@Valid EmployeeVo employeeVo, BindingResult result){... }
    • BindingResult 객체를 받아와 에러 검사를 할 수 있다.
    • 예시
@RequestMapping(...)

public String doGet(@Valid EmployeeVo employeeVo, BindingResult result) { 

    if(result.hasErrors()) {
	List<ObjectError> errors = result.getAllErrors();

       for(ObjectError error:errors) {
    		System.out.println(error.getDefaultMessage());
       }
       return "home";
    }

결론: @Valid..., BindingResult - 이 두 인자만 넣어줘도 Spring에서 자동으로 Data Binding, 검증, 결과 이 3가지 일을 전부 자동으로 해준다.

3. Data Buffering

- 사용자가 잘못된 입력을 한 뒤 페이지가 재요청되었을 때, 모든 속성을 다시 입력하는 수고를 덜어주어야 한다.

  • Web form에 content를 바인딩
  • 채워진 form bean들을 처리하기 위해, Spring은 data binding-aware tag들을 제공해준다.
    -> 서버에서 클라이언트로 속성 값들을 보내주는 형태
  • Spring form tag library를 사용하기 위해서는 JSP page 상단에
    <%@ taglib prefix=”sf" uri="http://www.springframework.org/tags/form"%>를 추가해주어야 한다.
  • 기존 HTML 태그가 Spring form tag library로 바뀐다.
    ex) <form> -> <sf:form>, <input type="text"> -> <sf:input>, <input type="password"> -> <sf:password>

JSP 수정

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

<sf:form method="post"
action="${pageContext.request.contextPath}/doget" modelAttribute="employeeVo">

   <table class="formtable">
   <tr>
      <td class="label">Name:</td>
      <td><sf:input class="control" path="name"/></td>
   </tr>
    ...
</sf:form>
</table>

</body>
</html>

 

Controller 수정

//수정 예시
@RequestMapping("/getemployeeVo")
public String getEmployeeVo(Model model) {

   model.addAttribute("employeeVo", new EmployeeVo());

   return "home";
}
//적용
@RequestMapping(value="/doGet", method=RequestMethod.POST)
public String doGet(@Valid EmployeeVo employeeVo, BindingResult result) {
	if(result.hasErrors()){
    	return "home";
    }
}

 

전달 과정

EmployeeVo의 속성 중 하나인 name값이 JSP의 <sf:input path="name"/>과 바인딩되어 값이 전달

참고

- Controller handler 메서드의 인자인 employeeVo는 자동으로 인스턴스화 되어 Model에 추가된다.

  • Error Messages
    - 사용자에게 요청이 거절된 이유를 안내하기 위해 에러 표시 코드를 추가
    • BindingResult 객체는 @Valid가 달린 Bean(EmployeeVo)과 같이 자동으로 Model에 삽입되어 Dispatcher Servlet을 통해 View로 전달된다.
    • Input 속성 밑에 error 태그를 추가하여 거절 이유를 표시한다.

예시)

<sf:form modelAttribute="employeeVo">

Name: <sf:input path="name" />
      <sf:errors path="name" sf:errors>

Email: <sf:input path="email" /> 
	<sf:errors path="email"></sf:errors>
…
</sf:form>

- 요청이 거절된다면 Bean 속성에 설정한 message discriptor대로 message가 view 상에 나타나게 된다.

 

 

요약: 따라서 Form bean은 Data binder, Data validator, Data buffer 역할을 하는 동시에 한다.

 

 

Reference

https://howtodoinjava.com/spring-mvc/spring-bean-validation-example-with-jsr-303-annotations/

 

Spring MVC Bean validation Example with JSR-303 Annotations

JSR-303 bean validation is a specification whose objective is to standardize the validation of Java beans through annotations. The objective of the JSR-303 standard is to use annotations directly in a Java bean class. This allows validation rules to be spe

howtodoinjava.com

 

'Spring > 이론' 카테고리의 다른 글

Logging (SLF4J and Logback)  (0) 2020.04.01
Spring Security  (0) 2020.03.30
MVC(Model-View-Controller)  (0) 2020.03.17
DB 연동(with Spring JDBC)  (0) 2020.03.09
관점 지향 프로그래밍(AOP, Aspect Oriented Programming)  (0) 2020.03.07

댓글