SPRING/스프링 MVC

핸들러 메소드 5부: @ModelAttribute

JUMP개발자 2021. 7. 3. 17:06

@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