[Spring] @RequestBody와 @RequestParam
프로젝트를 진행하던 중, form-Data와 json을 서버에서 처리하는 방식에 대한 오류를 다루던 중 알게된 @RequestBody와 @RequestParam의 명확한 차이를 정리해보자.
@ReqeustBody
조금 쉽게 설명하면 클라이언트가 전송하는 JSON을 받아오기 위해 특화된 어노테이션이라고 이해해도 좋다. 나는 Body에 있는 데이터 중 JSON이 아닌 바이트나 스트링이여도 알아서 되는 줄 알았던 바보같은 생각을 했던 것이다...
그래서 Multipart와 같이 바이트로 전달되는 것들은 파싱할 수 없다.
만약 클라이언트에서 "/nickname" 경로로 POST 요청을 보낸다고 해보자.
body에 아래와 같은 JSON 형태를 전송하게 된다면
{
"nickname": "dd",
"token": "123"
}
Controller에서는 아래와 같이 응답을 받을 수 있다.
@Getter
@NoArgsConstructor
public class UserNicknameRequest {
private String token;
private String nickname;
@Builder
public UserNicknameRequest(String token, String nickname) {
this.token = token;
this.nickname = nickname;
}
}
@PostMapping("/nickname")
public ResponseEntity changeNickname(@RequestBody UserNicknameRequest nicknameRequest){
String email = tokenProvider.decode(nicknameRequest.getToken());
userService.updateNickname(email, nicknameRequest.getNickname());
return ResponseEntity.ok(HttpStatus.OK);
}
당연하게 @RequestParam은 불가능했던 것이다.
@ReqeustParam
URL에 명시된 파라미터를 가져오는데 특화된 어노테이션이다. 특별하게 form-data와 더욱이 Multipart에서도 이 어노테이션을 통해서 값을 받아올 수 있다.
클라이언트가 "/nickname?toekn=123" 경로로 GET 요청을 보낸다고 해보자.
서버는 아래와 같이 요청을 처리할 수 있다.
@GetMapping("/nickname")
public ResponseEntity getNickname(@RequestParam("token") String token){
System.out.println(token);
return ResponseEntity.ok(HttpStatus.ok);
};
그럼 formData의 경우도 확인해보자. POST로 "/article"에 요청했다고 해보자.
{
"articleId": 1,
"rate": 1.5,
"writer": "사람",
"comment": "안녕하세요"
}
서버는 아래와 같은 형태로 데이터를 받을 수 있을 것이다.
@PostMapping("/review")
public ResponseEntity postReview(
@RequestParam("articleId") Long articleId,
@RequestParam("rate") Double rate,
@RequestParam("writer") String writer,
@RequestParam("comment") String comment) {
System.out.println("articleId = " + articleId);
System.out.println("rate = " + rate);
System.out.println("writer = " + writer);
System.out.println("comment = " + comment);
return ResponseEntity.ok(HttpStatus.ok);
};
참고자료
https://velog.io/@baekgom/MultipartFile-%EA%B3%BC-RequestPart-RequestParam-RequestBody