본문 바로가기
Dev/Spring

@InitBinder 어노테이션

by vellahw 2022. 10. 18.

 

스프링은 기본적으로 문자열을 지정한 타입의 값으로 변환할 때 Java빈의 Property Editor를 사용한다.

스프링 MVC가 HTTP 요청 파라미터를 객체의 프로퍼티 값으로 저장할 때 사용하는 WebDataBinder 역시 내부적으로 PropertyEditor를 사용하게 된다.

 

🎈. @InitBinder Annotation을 이용한 Date 타입 변환 처리

값이 '2021-12-24'인 HTTP 요청 파라미터를 java.util.Date 타입의 프로퍼티에 저장하고 싶을 때가 있는데, 이 경우 스프링 MVC의 WebDataBinder에 커스텀 PropertyEditor를 등록해주면 된다.

스프링은 java.util.Date 타입에 대한 PropertyEditor인 CustomDateEditor를 제공하고 있으며, 이 CustomDateEditor를 WebDataBinder에 등록함으로써 문자열을 Date 타입으로 변환할 수 있다.

따라서 다음과 같이 커맨드 클래스에 java.util.Date 타입의 프로퍼티를 추가해도 폼에 입력한 파라미터 값을 Date 타입의 프로퍼티로 전달받을 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Date;
            
public class QueryLogCommand {
            
    private Date from;
    private Date to;
    
    public Date getFrom() {
        return from;
    }
            
    public void setFrom(Date from) {
        this.from = from;
    }
            
    public Date getTo() {
        return to;
    }
            
    public void setTo(Date to) {
        this.to = to;
    }
}                   
cs

 

CustomDateEditor 클래스의 생성자는 첫 번째 파라미터로 String을 Date 타입으로 변환할 때 사용할 DateFormat을 전달받는다. 두 번째 파라미터는 값으로 null이거나 빈 문자열이 오는 것을 허용할 지의 여부를 지정한다.

1
2
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
cs

위 코드와 같이 두 번째 파라미터 값을 true로 지정하면 HTTP 요청파라미터 값이 존재하지 않거나 빈 문자열인 경우 null을 값으로 설정하게 된다.

반면에 두 번째 파라미터 값을 false로 설정하면 요청 파라미터 값이 존재하지 않거나 빈 문자열인 경우 검증 에러가 발생하게 된다. 이 때 에러 코드는 "typeMismatch"가 된다. 따라서 BindingResult를 통해서 에러 발생 여부를 확인할 수 있다.

 

 

💡. 예제

1) 커맨드 클래스 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package springMVC.controller;
 
import java.util.Date;
 
public class QueryLogCommand {
    
    private Date from;
    private Date to;
    
    public Date getFrom() {
        return from;
    }
    public void setFrom(Date from) {
        this.from = from;
    }
    public Date getTo() {
        return to;
    }
    public void setTo(Date to) {
        this.to = to;
    }
}
cs

 

2) 컨트롤러 클래스 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package springMVC.controller;
 
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
 
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class QueryLogController {
    
    @ModelAttribute("command")
    public QueryLogCommand formBaking() {
        return new QueryLogCommand();
        
    }
    
    @RequestMapping("/log/query.do")
    public String query(@ModelAttribute("command") QueryLogCommand command, BindingResult result) {
        return "/log/logList";
    }
    
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        binder.registerCustomEditor(Date.classnew CustomDateEditor(dateFormat, true));
    }
}
cs

 

3) dispatcher-servlet.xml에 설정 추가

1
<bean class="springMVC.controller.QueryLogController" />
cs

 

4) 뷰 파일 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>로그 목록</title>
</head>
<body>
<form:form method="get">
<form:errors path="from" element="div" />
<form:errors path="to" element="div" />
시작일: <form:input path="from" />
종료일: <form:input path="to" />
<input type="submit" value="조회" />
</form:form>
</body>
</html>
cs

 

실행 결과

 

시작일과 종료일 날짜 형식을 '-'가 아닌 문자로 입력 하면 에러 메세지가 뜨도록 properties 파일에 설정해둠

 

 

댓글