일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 우아한세미나
- 백준
- 트랜잭션
- 프리코스
- 의존성
- CircuitBreaker
- AWS
- yml
- Level2
- 우테코
- 스프링부트
- 우아한테크코스
- 세션
- JPA
- 미션
- Docker
- 자바
- AOP
- JUnit5
- REDIS
- Spring Batch
- mock
- HTTP
- 프로그래머스
- MSA
- Paging
- 코드리뷰
- 레벨2
- 스프링 부트
- 서블릿
- Today
- Total
늘
@RequestBody와 @ModelAttribute 차이 본문
@RequestBody
@RequestBody 애너테이션의 역할은 클라이언트가 보내는 HTTP 요청 본문(JSON 및 XML 등)을 Java 오브젝트로 변환하는 것이다.
기본 생성자만을 가지고 json값을 Java객체로 변환해준다.
MappingJackson2HttpMessageConverter 내부의 ObjectMapper를 통해 json값을 Java객체로 역직렬화를 한다. 직렬화가 가능한 클래스들은 기본 생성자가 항상 필수입니다.
즉, ObjectMapper를 통해 역직렬화가 이루어지므로 기본 생성자가 필수라는 말이다!
그렇다면 기본 생성자만을 보고 어떻게 필드를 알고 매핑을 해주는 것일까?
Jackson ObjectMapper는 Java 오브젝트의 필드에 맵핑할 때 getter혹은 setter매서드에서 (get, set)을 지우고 나머지 문자열을 참조하여 필드를 알아낸다고 합니다.
따라서 getter, setter 메서드가 모두 없다면 HttpMessageNotWriteableException이 뜹니다.
- 역직렬화에는 기본 생성자가 반드시 필요하다!
- JSNO, XML등의 데이터가 적합한 HttpMessageConverter를 통해 파싱 되어 Java 객체로 변환한다.
- 매개변수 있는 생성자와 Setter가 없어도 가능하다.
- 하지만 바인딩을 하려면 getter나 setter중 한 가지는 정의되어 있어야 한다.
@ModelAttribute
ModelAttribute를 사용하면 HTTP파라미터 데이터를 Java객체에 맵핑한다.
- Json형식은 처리가 안되고, Query String 및 Form형식 데이터만 처리할 수 있다.
- 필드와 바인딩하기 위해 매개변수 있는 생성자 또는 setter메서드가 필요하다.
또한 ResponseEntity를 통해 dto를 반환할 때, Dto에 getter가 없으면
No serializer found for class chess.web.controller.dto.RoomResponseDto$Title and no properties discovered to create BeanSerializer
위와 같이 에러가 발생한다.
getter를 추가해주면 에러는 사라지고 정상적으로 통신이 된다.
Serialize
- 직렬화
- Response
- Object to JSON
- getter를 사용한다.
Deserialize
- 역직렬화
- 리플렉션 이용
- Request
- JSON to Object
- 기본 생성자를 사용한다.
- getter나 setter가 필요하다.
추후에 인수테스트에서 리플렉션을 사용하면 기본생성자가 필요해서 response에서도 private으로 기본생성자를 만들어줄수 있다고 한다. 이 부분은 나중에 인수테스트를 직접 해보면서 다시 포스팅해야겠다.
추가 - 220518
리플렉션 api는 JVM으로 메모리(heap)에 올라간 영역에서 동적으로 객체의 값을 가져오므로 private으로 미리 올린 값들을 가져오기때문에 접근제어자의 영향을 받지 않는다고 생각한다.
Reference
https://tecoble.techcourse.co.kr/post/2021-05-11-requestbody-modelattribute/
https://da-nyee.github.io/posts/woowacourse-why-the-default-constructor-is-needed/
'백앤드 개발일지 > 스프링부트' 카테고리의 다른 글
[Spring bean lifecycle, hook]빈 생명주기 (0) | 2022.05.23 |
---|---|
@RestController와 @ResponseBody없이 json으로 통신하는 방법 (2) | 2022.04.30 |
[Gradle] runtimeOnly와 implementation와 testImplementation의 차이 (0) | 2022.03.31 |
[아키텍처] 계층형 아키텍처와 MSA (2) | 2022.02.11 |
[스프링 싱글톤] Bean과 Component 차이 (0) | 2022.01.14 |