일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- infcon 2024
- 전략패턴 #StrategyPattern #디자인패턴
- KPT회고
- 프로그래머스
- Python
- 빈 조회 2개 이상
- jwt
- 취업리부트코스
- 항해99
- 디자인패턴
- 개발자 취업
- 개발자부트캠프추천
- 단기개발자코스
- TiL
- 디자인 패턴
- DesignPattern
- 구글 OAuth login
- 프로그래머스 이중우선순위큐
- 인프콘 2024
- @FeignClient
- 빈 충돌
- Spring multimodule
- jwttoken
- 코딩테스트 준비
- JavaScript
- 1주일회고
- 99클럽
- 파이썬
- 커스텀 헤더
- spring batch 5.0
- Today
- Total
m1ndy5's coding blog
Jackson & Constructor 본문
프로젝트를 진행 중에 굉장히 난감한 문제를 겪었다.
문제는 아래와 같다.
// 댓글 다는 DTO
@Data
public class PostCommentReq {
private final Long accountId;
private final String content;
}
// 댓글 수정 DTO
@Data
public class PatchCommentReq {
private final String content;
}
댓글 다는 DTO는 전혀 문제가 없이 잘 작동을 했지만 댓글 수정 DTO는 제대로 된 값을 계속해서 못받아오는 상황,,,!!!
일단 @Data 가 무엇인지 살펴보자!
* Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.
@Data를 까보면 위와 같은 주석을 확인할 수 있는데, 해석해보자면
@Data는 @code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode 와 똑같다 라는 뜻
여기서 생성자와 관련된 곳은 바로 @RequiredArgsConstructor이다.
@RequiredArgsConstructor 이란?
@RequiredArgsConstructor은 초기화 되지 않은 final 필드나, @NotNull 이 붙은 필드에 대해 생성자를 생성해준다.
여기서 알 수 있는 점은 댓글 다는 DTO와 댓글 수정 DTO 모두 final을 붙여주었고 @Data가 @RequiredArgsConstructor을 포함하고 있으니까 인자 있는 생성자가 잘 작동해야한다고 생각했다.
하지만 결과는 댓글 다는 DTO는 인자 있는 생성자가 호출됐지만 댓글 수정 DTO는 인자 있는 생성자를 호출하지 못했다.
이에 대해 몇가지 시도를 해보았는데
- 댓글 수정 DTO의 필드에 final를 빼보았다.
final이 없기 때문에 기본 생성자로 호출이 된 것을 확인할 수 있었다. - 필드를 2개 이상으로 바꿔보았다.
이또한 인자 있는 생성자를 잘 호출하는 것을 확인할 수 있었다.
어떻게 된 것인지 알아보자!!
Jackson
json을 파싱하고 생성하는 라이브러리
내부적으로 Object Mapper class가 있어 json 파일을 파싱해서 자바 객체로 역직렬화 하거나, 자바 객체로부터 json을 직렬화시킬 수 있음
Jackson은 spring web dependency를 추가하면 자동으로 설치
Jackson은 Java Reflection을 사용
What is Java Reflection?
구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API
Java Reflection은 생성자의 인자 정보들을 가져올 수 없음
-> 따라서 기본 생성자 없이 파라미터가 있는 생성자만 존재한다면 java Reflection이 객체를 생성할 수 없게 됨
Jackson이 역직렬화를 할 때 반드시 기본 생성자가 필요한 이유였다.
그렇다면 왜 댓글 다는 DTO는 기본 생성자 없이 역직렬화가 가능했을까?
바로 jackson-module-parameter-names 모듈 덕분!
jackson-module-parameter-names 모듈은 기본 생성자가 없는 경우 필드에 데이터를 넣을 수 있는 다른 루트 검색 -> 인자가 있는 생성자로 바인딩
그래서 기본 생성자가 존재하지 않아도 다른 생성자에 역할을 위임해서 객체 바인딩 진행
그렇다면 여기서 또 아니 그래서 인자가 한 개인 생성자는 왜 바인딩이 안되는데!!
인자가 한개면 ObjectMapper가 모듈을 등록해도 역직렬화를 해주지 못한다고 함,,,(이유 아시는 분??ㅎㅎ)
그렇다면 어떻게 역직렬화를 해야할까?
기본생성자를 만들어주거나
@JsonCreator
public dto(String content){
this.content = content;
}
@JsonCreator 을 사용해주면 된다고 한다.
References
https://da-nyee.github.io/posts/woowacourse-why-the-default-constructor-is-needed/
https://beaniejoy.tistory.com/76
'백엔드 with java > spring' 카테고리의 다른 글
UnsatisfiedDependencyException (feat.영한님 강의) (2) | 2023.12.05 |
---|---|
Spring Security UserDetails, UserDetailsService (1) | 2023.10.11 |
정적 컨텐츠 VS MVC와 템플릿엔진 VS API (0) | 2023.03.07 |
View로 서버 잘 돌아가는지 확인하기 (0) | 2023.03.07 |
Spring Libraries (간단하게) (0) | 2023.03.07 |