오늘 모 부트캠프 2차 과제테스트를 보았는데.. 어이없는 부분에서 시간을 너무 쏟는 바람에 결국 완성하지 못하고 말았다. 컨트롤러 단에서 파라미터로 넘어온 값을 제대로 받지 못한 원인을 파악하지 못한 것이다. 이런 기본적인것도 제대로 해결하지 못했다는데에 많이 속상했고, 오늘 공부한 내용을 바로 글로 남기려 한다.
기존 프로젝트에서는 데이터를 모두 application/json 형태로 보내다보니 당연히 @RequestBody 형태로 데이터를 받았다보니, 테스트 케이스에서 multipart/form-data 형태로 들어오는 값의 파라미터가 모두 null로 받아와지는 것을 늦게 파악하고 말았다.
이에 HTTP 요청의 데이터를 받는 4가지 방법에 대해 정리해보겠다.
@RequestBody
-
내부 동작
- MappingJackson2HttpMessageConverter 사용
- 생성자와 Setter 없이도 가능 (물론 기본생성자는 필요)
- ObjectMapper를 사용해 JSON 값을 Java 객체로 역직렬화
- 역직렬화 : 생성자를 거치지 않고 리플렉션을 사용해 객체를 구성
- 직렬화 가능한 클래스는 기본 생성자가 필수로 필요
- ObjectMapper에 의해 데이터 바인딩을 위한 필드 명을 알아내기 위해 getter나 setter 중 1개는 필요
-
사용 경우
- 주로 Ajax 요청 (application/json)에서 사용
- 주로 JSON, XML, 기타 데이터 형식의 요청 처리시 사용
- 클라이언트 단에서 요청 시 반드시 Content-Type을 명시해줘야함
- binary 파일을 포함하고 있지 않은 데이터를 받는 역할
- 따라서 multipart 요청은 불가
- multipart/form-data: 파일 업로드시 사용되며 '파일을 비롯한 여러 데이터가 있음'이라는 뜻을 가짐. (@RequestBody로 받을 수 없음 !!)
@ModelAttribute
@RequestParam
@RequestPart
- 사용 경우
- @RequestBody가 필요하지만 Binary Stream이 포함되는 경우(MultipartFile과 같은)에 사용
- 내부 동작
- MultipartFile이 포함되는 경우에 MultipartResolver가 동작하여 역직렬화
- MultipartFile이 포함되지 않는 경우엔 @ReqeustBody 같이 HttpMessageConverter가 동작
요약
-
@RequestBody
- content-type이 application/json 형태 요청에 사용. multipart/form-data 요청에 사용 불가
- 생성자와 Setter 없이도 가능
-
@ModelAttribute
- Content-type이 multipart/form-data의 형태를 받을때 사용 가능
- 값에 직접 접근할 수 있는 생성자나 기본생성자 + setter가 필요
-
@RequestParam
- 한개의 파라미터만 받을 때 사용
- 기본 설정은 반드시 값을 받아야함으로, 만약 값이 들어오지 않을 수도 있다면 required=false를 설정
-
@RequestPart
- Binary Stream이 포함되는 경우(MultipartFile과 같은)에 사용
- 파일 업로드 시 파일 크기 제한, 요청 전체 크기 제한 등의 옵션 제어 필요
spring:
servlet:
multipart:
max-file-size: 2MB
max-request-size: 10MB
file-size-threshold: 0
참고자료
https://tecoble.techcourse.co.kr/post/2021-05-11-requestbody-modelattribute/
https://devhooney.tistory.com/179
https://middleearth.tistory.com/35