@RequestBody
를 쓰면,final
로 설정할 경우, Setter가 없고 기본생성자로 초기화를 한다.❓ 왜 기본생성자 + Setter 인가요?
기본 생성자로 객체를 만들고, 생성자에서 값을 못받았기 때문에
데이터를 바인딩하려면 반드시 Setter가 필요하다!
@Getter
public class ScheduleRequestDto {
@NotBlank(message = "제목을 입력해주세요.")
@Size(max = 50, message = "제목은 50자 이내로 입력해주세요.")
private final String title;
@NotBlank(message = "내용을 입력해주세요.")
@Size(max = 200, message = "내용은 200자 이내로 입력해주세요.")
private final String contents;
// ✅ 생성자 = @RequiredArgsConstructor
public ScheduleRequestDto(String title, String contents) {
this.title = title;
this.contents = contents;
}
}
jackson-module-parameter-names
가DTO에서도 필요한 경우가 있고,
엔티티 클래스의 경우 필수로 필요하다.
// 기본생성자 예시
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public final class RequestDto {
private String searchText;
private String searchType;
}
기본 생성자의 접근 제한자를 protected
로 선언하자
public
또는 protected
를 많이 쓰는 듯?
❓ @NoArgConstructor 어노테이션
- 매개변수가 없는 기본 생성자를 생성하는 어노테이션
- 기본 생성자로 무분별하게 값을 주입하게 되면, DTO를 신뢰할 수 없으므로
❗️기본 생성자가 필요할 경우, access를 반드시 두자.
Jackson 라이브러리에게 역직렬화에 사용할 생성자가 누구인지 알려줘야 한다.
이 때 @JsonCreator
를 사용한다.
@Getter
public final class RequestDto {
private final String searchText;
private final String searchType;
// ✅ 역직렬화를 수행하는 생성자 지정
@JsonCreator
public RequestDto(String searchText,
String searchType) {
this.searchText = searchText;
this.searchType = searchType;
}
public RequestDto(String searchText) {
this.searchText = searchText;
this.searchType = null;
}
}
@JsonProperty
를 붙여야 한다..❓ 직렬화/역직렬화..?
- 직렬화: Java 객체(DTO) → JSON: (서버가 클라이언트에게 응답 )
- 역직렬화: JSON → Java 객체(DTO): (클라이언트가 서버에게 요청)
record
를 사용할 수도 있지만QueryString, FormData를 받기위한 DTO는 final로 설정하는 것이 국룰이다.
→ 불변성 보장, 신뢰할 수 있는 객체 설계
기본 생성자의 경우, 최대한 접근제어자를 통해 관리하자.
→ 무분별한 객체 생성 방지
생성자가 두개 이상일 경우
→ @JsonCreator
로 어떤 생성자를 사용할 것인지 지정해주어야 한다.