개발하면서 Controller에서 Request body로 name 값만 받아야 하는 상황이 있어서 다음과 같이 한번 받아봤는데 문제가 발생했다.
당연하게 DTO를 정의해서 사용해왔지만 왜 안되는거지에 대한 궁금증이 생겼다.
// POST
{
"name" : "hi"
}
@PostMapping("/example")
public ResponseEntity<?> example(@RequestBody String name){
System.out.println(name);
}
위 요청을 보내면 다음과 같이 콘솔에 찍히게 된다.
기대 했던 값은 hi 였지만 JSON Body 자체가 매핑 되는 걸 볼 수 있다..
Spring은 요청 본문을 파싱하여 개별 필드로 매핑하는 대신 요청 본문 전체를 String 변수에 직접 할당한다고 한다.
따라서, JSON 구조 { "name": "hi" }가 아니라 전체 JSON 문자열 자체가 name 파라미터에 저장되게 되는 것이다.
@RequestBody
어노테이션이 HTTP 요청 본문의 내용을 Java 객체로 변환하는 과정에서 HttpMessageConverter
를 사용하게 되는데 String 타입의 경우 Spring은 본문을 객체로 변환하는 대신 요청 본문 전체를 단순 문자열로 간주하고, 이를 String 파라미터에 할당한다고 한다.
따라서 JSON의 특정 필드를 직접 매핑하려면 JSON 구조에 해당하는 DTO 를 정의하고 이 객체를 Request 와 매핑 시켜야 한다!!!