@ModelAttribute와 @Validated를 이용한 Form요소 전달 예제
예전에는 Request.Get, Request.Post를 통해 html의 폼 요소를 일일이 받아서 변수에 담아 개발을 하던 시절이 있었다. 엄청난 노가다성 코딩이 필수불가 사항이었던 시절인데 요즘 스프링을 하면서 참 좋아진 세상이란걸 느끼고 있다. 다양한 애너테이션을 통해 효율적인 프로그래밍이 가능해졌기 때문이다.
@ModelAttribute를 이용한 폼 요소 처리 예제를 정리해본다.
@ModelAttribute
CustomerForm setUpForm() {
return new CustomerForm();
}
@RequestMapping(method = RequestMethod.GET)
public String list(Model model) {
List<Customer> customers = customerService.findAll();
model.addAttribute("customers", customers);
return "customers/list";
}
@RequestMapping(value = "create", method= RequestMethod.POST)
public String create(@Validated CustomerForm form, BindingResult result, Model model) {
if(result.hasErrors()) {
return list(model);
}
Customer customer = new Customer();
BeanUtils.copyProperties(form, customer);
customerService.create(customer);
return "redirect:/customers";
}
@ModelAttribute애너테이션을 붙인 메서드는 컨트롤러 안에 있는 @RequestMapping으로 매핑된 메서드보다 먼저 실행되며, 반환 값은 Model에 자동으로 추가된다. 이 예제에서는 list()나 create() 메서드가 호출되기 전에 model.addAttribute(new CustomerForm()) 부분이 실행. (addAttribute()에서 속성 이름을 생략하면 속성 값의 클래스 이름에서 첫 문자를 소문자로 쓴 문자열이 사용된다.)
@Validated애너테이션은 폼에서 입력되어 들어온 값을 검사하기 위해 사용된다. Bean Validation애너테이션이 적용되고 그 결과값이 옆에 있는 BindingResult인자에 저장된다.
org.springframework.beans.BeanUtils를 사용하고, 필드의 이름과 타입이 같을 때만 사용된다. 좀더 유연한 Bean 변환을 구현하려면 Dozer나 ModelMapper를 이용하는 방법도 있다.
CustomerForm을 만들지 않고 Customer를 그대로 사용할 수 도 있는데 화면에서 전송할 폼 항목 수가 DB에 저장할 정보 수보다 많을 때도 있을 것이다.
예를 들어 암호 항목과 확인용 암호 항목을 폼으로 전송할 때 확인용 암호 항목은 보통 DB에 저장하지 않는다.
따라서 Customer클래스에 확인용 암호 필드는 필요 없다.
이처럼 Customer클래스가 화면 상황에 따라 지저분해지지 않도록 화면 정보는 CustomerForm클래스에서 표현하고,
컨트롤러에서 변환하는 방법을 사용하는 것이 좋다. 조금 번거롭다고 느낄 수 있지만 이렇게 하면 애플리케이션을 유지보수하기 편리하다.
그리고 롬복을 사용하면 폼을 표현하는 클래스를 만드는 비용이 줄고, Dozer나 ModelMapper등을 사용하면 변환 처리를 구현하는 비용도 낮아진다.
'프로그래밍 > Spring' 카테고리의 다른 글
WebSecurity configure (0) | 2019.04.25 |
---|---|
@RequestMapping의 params (0) | 2019.04.23 |
스프링 MVC Location 헤더에 리소스URI 설정 예제 (0) | 2019.04.19 |
JPA를 이용한 페이징 처리 구현 예제 (0) | 2019.04.17 |
@Query어노테이션, JPQL(Java Persistence Query Language) (0) | 2019.04.17 |