Framework/spring

Spring3 @ModelAttribute 사용시 Date 값 매핑방법

jeeyong 2012. 5. 18. 10:39

Spring MVC 모델를 사용할때 @ModelAttribute 라는 어노테이션 기능이 있다. 이 기능을 간단하게 설명하자면 보통 form 입력을 받을 경우

/** 일반적인 파라메터 객체에 주입방법 **/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	String parameter1 = request.getParameter("parameter1");	
	String parameter2 = request.getParameter("parameter2");
	String parameter3 = request.getParameter("parameter3");
	String parameter4 = request.getParameter("parameter4");

     User user = new User();

     user.setParameter1(parameter1);
     user.setParameter2(parameter2);
     user.setParameter3(parameter3);
     user.setParameter4(parameter4);

			...
}

이런 식으로 파라메터로 받은 소스를 객체에 놓는 코드를 작성해야하는데 이런 소스를 줄여준다고 생각하자, 한마디로 넘어온 파라메터 값중에 ModelAttribute로 등록된 객체의 속성과 매팅되는 값이 있을 경우 자동으로 바인딩을 해준다. 라는 것인데 사용방법은 아래와 같다. 

/** 일반적인 파라메터 객체에 주입방법 **/
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(
	@ModelAttribute("customer") Customer customer,
	BindingResult result, SessionStatus status) {
 
	customerValidator.validate(customer, result);
 
	if (result.hasErrors()) {
		//if validator failed
		return "CustomerForm";
	} else {
		status.setComplete();
		//form success
		return "CustomerSuccess";
	}
}

간단하고 쉽기 때문에 사용자 가입정보 같이 매우 많은 form 전송으로 받을때 매우 유용하다.

그러나 그대로 사용할 경우 문제가 생긴다. 그 문제는 바로 Date값 같은 객체를 받을 경우라고 할수있다. 보통 form으로 넘어오는 객체는 전부 String으로 받는다라고 가정된다. 그리고 매핑시 객체(여기에선 Customer 객체)가 가지고 있는 속성중 int나 float 같은 자료형은 자동 형변환이 되어서 들어가는것 같은데 Date경우 스트링을 Date값을 형변환을 위해선 넘어온 String의 fomat을 명시 해줘야 하는데 이 부분을 어떻게 해결해야하느냐인 것이다. 이것이 해결되지 않으면 반쪽자리 맵핑으로 작업을 해야하는 것이다.

이제 그 해답을 밝히자면..

아! 이방법은 두가지로 나뉠수있는데 Spring3에서 어노테이션을 사용하는 것과 Spring3이하를 사용하는 프로젝트라면 어노테이션을 사용하지 않은 상황에서 해결하는 방법이 있다.

첫째로 Spring3에서 어노테이션을 사용하는 방법으로

/** 어노테이션을 이용한 방법 **/
@InitBinder
public void initBinder(WebDataBinder binder) {
	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
	binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}

이부분을 Controller에 추가로 입력하는 것이다.

Spring3이하를 사용하는 프로젝트라면,

/** Spring3이하 버젼에서 이용하는 방법(어노테이션X) **/
protected void initBinder(HttpServletRequest request,
	ServletRequestDataBinder binder) throws Exception {

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

간단하게 전체적으로 요약하자면

/** 전체 소스 **/
@Controller
public class InsertController {
     
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }

    @RequestMapping("/processSubmit")
    public String processSubmit(@ModelAttribute("customer") Customer customer, BindingResult result, SessionStatus status){
         
        if (result.hasErrors()) {
            //if validator failed
            return "CustomerForm";
        } else {
            status.setComplete();
            //form success
            return "CustomerSuccess";
       }
    }
}

위의 방법처럼 간단히 추가만해주면된다.

끗.