핸들러 메소드 5부: @ModelAttribute
@ModelAttribute
- 여러 곳에 있는 단순 타입 데이터를 복합 타입 객체로 받아오거나 해당 객체를 새로 만들 때 사용할 수 있다.
- 여러 곳? URI 패스, 요청 매개변수, 세션 등
- 생략 가능
값을 바인딩 할 수 없는 경우에는?
- BindException 발생 400 에러
바인딩 에러를 직접 다루고 싶은 경우
- BindingResult 타입의 아규먼트를 바로 오른쪽에 추가한다.
바인딩 이후에 검증 작업을 추가로 하고 싶은 경우
- @Valid 또는 @Validated 애노테이션을 사용한다.
@Controller
public class SampleController {
@PostMapping("/events/valid")
@ResponseBody
public Event getEvent(@ModelAttribute @Valid Event event,
BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
System.out.println("=======================");
bindingResult.getAllErrors().forEach(c->{
System.out.println(c.toString());
});
}
return event;
}
public class Event {
private int id;
// Not Null
@NotNull
private String name;
// 최소 30
@Min(30)
private Integer limit;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
}
name : Not Null / limit : 최소 30
메시지 : Field error in object 'event' on field 'limit': rejected value [-222]; codes [Min.event.limit,Min.limit,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [event.limit,limit]; arguments []; default message [limit],30]; default message [30 이상이어야 합니다]
@ModelAttribute ->RequestBody의 경우
@Controller
public class SampleController {
@PostMapping("/events/valid")
@ResponseBody
public Event getEvent(@RequestBody @Valid Event event,
BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
System.out.println("=======================");
bindingResult.getAllErrors().forEach(c->{
System.out.println(c.toString());
});
}
return event;
}
public class Event {
private int id;
// Not Null
@NotNull
private String name;
// 최소 30
@Min(30)
private Integer limit;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
}
@RequestBody의 Header :
Content-Type : application/json
@ModelAttribute의 Header :
Content-Type : application/x-www-form-urlencoded