@ModelAttribute에 대해 개념을 확실히 잡고싶어서 따로 정리하고자 한다.
@ModelAttribute
- @ModelAttribute를 사용하지 않으면 @RequestParam을 통해 요청 파라미터를 받고 객체 생성 후 setXxx()를 통해 직접 값을 세팅해줘한다.
- 하지만 @ModelAttribute를 사용하면 spring은 위 작업을 자동으로 해준다.
@Data
class Hello {
private String username;
private int age;
}
// 어노테이션 생략
public String modelAttributeV1(@ModelAttribute Hello hello){
...
return "ok";
}
[동작]
- Hello 객체를 생성한다.
- 요청 파라미터의 이름으로 Hello 객체의 프로퍼티를 찾는다.
- 해당 프로퍼티의 setXxx()를 호출해서 값을 바인딩한다.
프로퍼티?
- 객체가 getXxx()나 setXxx()가 있으면 xxx라는 프로퍼티를 가지고있다.
- get, set을 떼고 맨 첫글자를 소문자로 바꾼 것
HTTP 메시지 바디를 통해 데이터가 넘어오는 경우는 @RequestParam,@ModelAttribute를 사용할 수 없다. 하지만 폼 형식은 요청 파라미터로 인정한다.
@ModelAttribute를 이용해서 폼 데이터로 입력값을 바인딩하려는 경우, input태그의 name 속성이 바인딩하려는 객체의 속성 이름과 동일해야하고 타입도 주의해야한다.
@ModelAttribute 생략
- @ModelAttribute는 생략이 가능하다.
// 어노테이션 생략
public String modelAttributeV1(Hello hello){
...
return "ok";
}
- 하지만 @RequestParam도 생략이 가능한데 구분은 어떻게 하느냐?
- String, Integer과 같은 단순타입은 @RequestParam이 생략된걸로
- 나머지는 @ModelAttribute가 생략된걸로
- 정확히 얘기하면 @ModelAttribute는 argument resolver로 지정해둔 타입 외를 말한다.
- 생각하면 된다.
- 그럼 또 궁금한게 생겼다. argument resolver는 뭐지?
@ModelAttribute("name") name 속성
- @ModelAttribute("name") name 속성을 줄 수 있다.
- 그래서 모델에 @ModelAttribute로 지정한 객체를 자동으로 넣어준다.
// 어노테이션 생략
public String modelAttributeV1(@ModelAttribute("hello") Hello hello){
...
return "ok";
}
- model.attribute("hello", hello)가 자동으로 추가되어model.attribute("hello", hello) 코드를 생략해도된다.
- 더 나아가서 name속성도 생략이 가능하다.
- name속성을 생략하면 클래스명의 첫글자를 소문자로 변경한 이름으로 등록된다.
- 위 코드같은 경우 Hello -> hello라는 이름으로 모델에 담긴다.