[REST][Spring] @ModelAttribute에 @setter 필요 vs @Requestbody엔 필요X
문제
- 컨트롤러에서 GET mapping @ModelAttribute로 받을 때, 객체에 @setter없으면 @ModelAttribute로 parameter에서 값 가져와서 객체 instantiate 하는게 안되고 다 null로 채워짐
- POST mapping @RequestBody는 setter 없어도 맵핑 잘 됨
// 객체
@Getter
class Dummy {
private String name;
private int age;
}
// GET /host?name=goldenriver4422&age=19
@GetMapping
public List<Data> fetchByCondition(@ModelAttribute Dummy){
// Dummy(name=null, age=null) 🔥 fields not set
return repo.find(Dummy.toQuery());
}
// GET /host
/*
Body JSON
{
name: goldenriver4422
age: 19
}
*/
@PostMapping
public Data save(@RequestBody Dummy){
// Dummy(name=goldenriver4422, age=19)
return repo.find(Dummy.toQuery());
}
원인
요약
https://minchul-son.tistory.com/546
1. @ModelAttribute - 적절한 생성자 찾아서 객체 instantiate 하고, 나머지 값들은 setter로 설정해줌
2. @RequestBody - 아래 3가지 과정 거침
1) HTTP req body는 HTTP Message Converter로 변환;
2) JSON 형식으로 전달된 body는 HTTP Message Converter 구현체중 하나인 Jackson2HttpMessageConverter를 통해 Java 객체로 변환
3) 이때 ObjectMapper를 사용하기 때문에 setter 필요 없음
https://jojoldu.tistory.com/407
query parameter냐 body냐에 따라 객체(DTO)에 mapping 담당하는 담당자가 다름
1. @RequestBody - Jackson2HttpMessageConverter (DTO에 setter 필요x)
2. @ModelAttribute - WebDataBinder (DTO에 setter 필요! ✅)
👍 테스트 코드 작성 (MockMvc, ObjectMapper)
부족한 지식
- object mapper, argument resolver등 개념 - 이름만 들어봤음, high level로만 이해
- 직접 이렇게 테스트 짜서 확인하는거