[Spring MVC] Handler Method 핸들러 메서드 @ModelAttribute
@ModelAttribute
1. Method Level
@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("msg", "Welcome to the Netherlands!");
}
하나 이상의 속성을 Model에 추가하고 싶을 때 메서드 레벨에서 @ModelAttribute를 추가해준다. 일반적으로 Spring MVC는 요청 핸들러 메서드를 호출하기 전에 항상 해당 메서드를 먼저 호출한다. 즉, @RequestMapping 어노테이션이 달린 컨트롤러 메서드가 호출되기 전에 @ModelAttribute 어노테이션이 달린 메서드가 호출된다. 시퀀스의 논리는 컨트롤러 메서드 내에서 처리가 시작되기 전에 모델 개체를 만들어야한다는 것이다.
2. Method Argument Level
@ModelAttribute는 여러 곳에 있는 단순 데이터 타입을 복합 타입 객체로 받아오거나 해당 객체를 새로 만들 때 사용할 수 있다.
여러 곳은 URI path, 요청 매개변수, 세션 등을 의미한다.
복합 객체에 데이터 바인딩을 하는 방법은 @RequestParameter로만 전달되어야하는 것은 아니다.
유연하게 여러 데이터를 하나의 복합 타입 객체로 받아올 수 있다.
만약 값을 바인딩할 수 없는 경우라면 BindException이 발생하고 400 에러가 발생한다.
만약 바인딩 에러를 직접 다루고 싶은 경우라면 @ModelAttribute가 붙은 메서드에 BindingResult 파라미터를 추가하면 된다.
@Controller
@RequestMapping("/event")
public class SampleController {
@PostMapping("/names/{name}")
@ResponseBody
public Event getEvent(@ModelAttribute Event event, BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
bindingResult.getAllErrors().forEach( c -> {
System.out.println(c.toString());
});
}
return event;
}
}
바인딩 이후 검증 작업을 추가로 진행하고 싶다면 @Valid 또는 @Validated 어노테이션을 사용할 수 있다.
// Event.java
@Getter
@Setter
public class Event {
private Long id;
private String name;
@Min(0)
private Integer limit;
}
// SampleController.java
@Controller
@RequestMapping("/event")
public class SampleController {
@PostMapping("/names/{name}")
@ResponseBody
public Event getEvent(@Valid @ModelAttribute Event event, BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
bindingResult.getAllErrors().forEach( c -> {
System.out.println(c.toString());
});
}
return event;
}
}
@Validated
스프링 MVC 핸들러 메서드 아규먼트에 사용할 수 있으며, Validation group 이라는 힌트를 사용할 수 있다.
@Valid 어노테이션에는 그룹을 지정할 방법이 없지만 @Validated는 스프링이 제공하는 어노테이션으로 그룹 클래스를 설정할 수 있다.
참고
https://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation
https://minkukjo.github.io/framework/2020/04/13/Spring-85/
'web > Spring' 카테고리의 다른 글
[Spring JPA] 대량의 데이터를 삭제할 때 batch delete query (0) | 2022.05.23 |
---|---|
[Spring] @RequestBody vs @ModelAttribute (0) | 2022.04.21 |
[Spring MVC] Thymeleaf에서 List 보여주기 (How to bind a List object in Thymeleaf) (0) | 2022.04.18 |
[Spring Boot] Scheduler 사용하기 (일정 주기로 실행하는 스프링 스케쥴러) (0) | 2022.04.13 |
[Spring] 빈 생명주기 콜백 - @PostConstruct, @PreDestroy (2) | 2022.04.12 |
댓글 개