작성
·
718
3
우선 수업 잘 듣고 있습니다 호돌맨님! 많이 배우고 있어요 ㅎㅎ
제목에서와 같이 PostCreate 부분에서 기본 생성자에 관해 질문을 드립니다.
// @Setter
@Getter
@NoArgsConstructor // TODO: 왜 이게 꼭 있어야 하는 것일까?
public class PostCreateDto {
@NotBlank(message = "타이틀을 입력해주세요.")
private String title;
@NotBlank(message = "내용을 입력해주세요.")
private String content;
@Builder
public PostCreateDto(String title, String content) {
this.title = title;
this.content = content;
}
}
우선 이건 제 코드입니다. 보시면 제 코드에는 @NoArgsConstructor 어노테이션이 있는데요. 이 부분이 없으면 제 PostControllerTest에서는 테스트 실패가 뜨더라구요.
에러 메시지는 다음과 같습니다.
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.blog.request.PostCreateDto
(no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
에러메시지를 읽어보니 생성자가 없다는 문제 같아서 @NoArgsConstructor 어노테이션을 붙여보니 정상적으로 작동을 하더군요.
이 부분이 궁금해서 찾아보니 RequestBody로 넘어오는 데이터를 맵핑할 때 Jackson의 ObjectMapper가 사용되는데 이게 RequestBody를 생성할 때, DTO가 Property기반이 아니거나 Delegate를 한 상태가 아니라면 기본 생성자로 생성한다 라고 나와있네요. (https://velog.io/@conatuseus/RequestBody%EC%97%90-%EC%99%9C-%EA%B8%B0%EB%B3%B8-%EC%83%9D%EC%84%B1%EC%9E%90%EB%8A%94-%ED%95%84%EC%9A%94%ED%95%98%EA%B3%A0-Setter%EB%8A%94-%ED%95%84%EC%9A%94-%EC%97%86%EC%9D%84%EA%B9%8C-3-idnrafiw)
그리고 바인딩할 때 Setter가 없이도 자바 리플렉션을 통해서 DTO에 값이 들어간다고 하는 것도 이번에 알게 됐네요. 그래서 Setter를 지우고 Getter랑 @NoArgsConstructor 어노테이션만 붙이고 테스트를 돌려보니 통과가 잘 됩니다.
그런데 호돌맨님이 올려주신 코드를 보니 PostCreate 부분에 기본생성자가 없더라구요. 그런데도 테스트통과가 잘 되는 것을 보니까 신기하네요. 어떻게 그게 가능한 것인지 설명해주실 수 있나요?
답변 1
1
안녕하세요. 호돌맨입니다.
질문을 남겨주셔서 감사합니다.
한 줄 요약: @Setter는 필요없습니다.
@Getter
@ToString
public class PostCreate {
@NotBlank(message = "타이틀을 입력하세요.")
private String title;
@NotBlank(message = "콘텐츠를 입력해주세요.")
private String content;
}
값이 잘 입력됩니다. 기본 생성자가 있기때문에 문제 없을것같네요
@Getter
@ToString
public class PostCreate {
@NotBlank(message = "타이틀을 입력하세요.")
private String title;
@NotBlank(message = "콘텐츠를 입력해주세요.")
private String content;
@Builder
public PostCreate(String title, String content) {
this.title = title;
this.content = content;
}
}
생성자를 통해 값이 들어갑니다.
테스트시 생성자가 없는경우 title, content 값을 어떻게 입력 해야할지는 고민을 해봐야겠네요.
감사합니다.