Troubleshooting
발생한 문제
@PostMapping("{id}")
public boolean checkPassword(@RequestBody String password, @PathVariable long id) {
System.out.println("password = " + password);
return blogService.checkPassword(id, password);
}
요청
결과
- 위 json 데이터를 요청 보내면 코드 상으로 password 값에 pw가 String 타입으로 있을 거라고 기대했지만 josn 형태로 그대로 들어가있다.
해결 과정
- 보통 아래의 코드처럼 User 객체를 json 형태로 보냈을 때 user.getName() 의 반환값으로 "wisdom" 이 String 타입으로 들어가있다. @RequestBody 가 내부적으로 바꿔준다 라는 것만 알고 있었는데 @RequestBody 어노테이션이 어떻게 동작하는지 원리를 파악할 필요가 있다고 느꼈다.
{
"name": "wisdom",
"email": "wisdom@gmail.com"
}
// request body에 json 데이터를 보낸다.
@RequestBody User user
@RequestBody
- 구글링을 하다보면 @RequestBody의 정의로 클라이언트가 전송하는 Json(application/json) 형태의 HTTP Body를 Java 객체로 변환시켜주는 역할을 한다라고 적혀있는 경우가 많다. 맞는 말이기도 하지만 너무 한정적인 정의라고 생각한다.
- 먼저 @RequestBody 는 JSON 뿐만 아니라 plain text, xml 등 다양한 포맷을 내부적으로 다룬다.
@RequestBody 동작 순서
- HTTP Clients 가 request body에 데이터를 담아 request 를 보낸다.
- 컨트롤러 메서드에 @RequestBody 어노테이션이 명시되어 있으면 해당 어노테이션이 스프링에게 request body에 담긴 데이터를 도메인 객체로 역직렬화 처리 하라고 알려준다.
- 추가적으로 자바 Map 으로도 역직렬화 처리를 해준다.
@RequestBody 정리
- 스프링 컨트롤러의 핸들러 메서드에서 사용하는 어노테이션이다.
- 해당 어노테이션이 나타내는 것은 스프링에서는 request body를 객체로 deserialize 해줘야 한다는 것이다.
- 그리고 그 변환된 객체가 핸들러 메서드의 파라미터로 전달된다.
- 내부적으로 역직렬화는 많은 구현체 중의 하나인 MessageConverter 가 담당한다.
- 서버로 들어오는 데이터를 오브젝트로 가공하거나 비즈니스단에서 처리된 오브젝트를 http 메시지로 변환하는 역할을 담당한다.
@RequestBody 어노테이션을 사용하면 request body를 도메인 객체가 아닌 자바 Map 으로도 역직렬화할 수 있다.
public boolean checkPassword(@RequestBody Map<String, String> passwordMap, @PathVariable long id) {}
- 위 코드처럼 컨트롤러 메서드 파라미터에 @RequestBody 어노테이션을 명시하고 파라미터의 형태를 Map<String, String> 형태로 전달하면 내부적으로는 HttpMessageConverter 처리해준다.
해결
@PostMapping("{id}")
public boolean checkPassword(@RequestBody Map<String, String> passwordMap, @PathVariable long id) {
System.out.println("stringMap.get(\"password\")" + passwordMap.get("password"));
return blogService.checkPassword(id, "pw");
}
- 위와 같이 Map<String, String> 형태로 받아서 get 메서드로 password 값을 가져왔다.
회고
- 어노테이션 하나로 스프링 내부적으로 정말 바쁘게 움직이는 거 같다. 다음에 기회가 되면 역직렬화에 대해서도 공부해보고 싶고 MessageConverter 에 대해서도 자세히 분석을 해봐야겠다.