728x90
Lombok과 직렬화/역직렬화: 문제와 해결 방법
Lombok의 @Getter, @Setter, @AllArgsConstructor, @NoArgsConstructor는 코드 작성의 편리함을 제공합니다. 그러나 Java의 직렬화/역직렬화(Jackson, Gson, 기본 직렬화 등)와 함께 사용할 때 문제가 발생하기도 합니다. 이번 글에서는 이러한 문제를 다루고, 해결 방법과 설계 가이드를 제시합니다.
직렬화와 역직렬화란?
1. 직렬화(Serialization)
- 정의: 객체를 바이트 스트림으로 변환하여 파일 저장, 네트워크 전송 등에 사용할 수 있도록 만드는 과정입니다.
- 사용 사례:
- 객체 데이터를 파일에 저장할 때.
- HTTP API 응답으로 JSON 형식의 데이터를 반환할 때.
2. 역직렬화(Deserialization)
- 정의: JSON, XML, 바이트 스트림 등을 객체로 복원하는 과정입니다.
- 사용 사례:
- 외부 시스템으로부터 받은 데이터를 객체로 변환할 때.
- HTTP 요청에서 JSON 데이터를 Java 객체로 매핑할 때.
Lombok과 직렬화/역직렬화의 문제점과 해결 방법
1. 기본 생성자 누락 문제
- 문제 상황:
- 역직렬화 라이브러리(Jackson, Gson 등)는 기본 생성자를 통해 객체를 생성합니다.
- 그러나 클래스에 @NoArgsConstructor가 없으면 기본 생성자가 없어서 역직렬화 시 InstantiationException이 발생합니다.
- 해결 방법:
- @NoArgsConstructor를 추가하여 기본 생성자를 제공해야 합니다.
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String name;
private int age;
}
2. 필드 초기화 문제
- 문제 상황:
- 기본 생성자로 객체를 생성한 뒤, 역직렬화 과정에서 필드 값이 제대로 설정되지 않아 null이 반환될 수 있습니다.
- 이는 JSON 데이터를 필드에 매핑할 때, 필드 접근 권한이나 Lombok 설정이 올바르지 않을 경우 발생합니다.
- 해결 방법:
- 필드 접근 권한(private)을 유지하면서, @Getter 및 @Setter를 추가해 Jackson이 값에 접근할 수 있도록 설정합니다.
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String name;
private int age;
}
3. @AllArgsConstructor와 @NoArgsConstructor 혼용 문제
- 문제 상황:
- @AllArgsConstructor만 사용하면 역직렬화가 실패합니다. 이는 Jackson이 JSON 데이터를 객체로 변환할 때 기본 생성자가 필요하기 때문입니다.
- 또한 JSON 데이터에 특정 필드가 누락되면, 해당 필드가 null로 설정될 수 있습니다.
- 해결 방법:
- @AllArgsConstructor와 @NoArgsConstructor를 함께 사용하여 기본 생성자와 필드 초기화 생성자를 모두 제공합니다.
- 필요한 경우, JSON 필드 이름을 명시적으로 매핑하기 위해 Jackson의 @JsonProperty를 사용합니다.
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class User {
@JsonProperty("user_name")
private String name;
private int age;
}
4. 필드 초기화와 기본값 문제
- 문제 상황:
- 기본 생성자로 생성된 객체는 필드 값이 초기화되지 않아 예상치 못한 기본값(예: null, 0)으로 설정될 수 있습니다.
- JSON 데이터를 매핑할 때도 기본값이 덮어쓰여질 위험이 있습니다.
- 해결 방법:
- 필드에 기본값을 명시하거나, Lombok의 @Builder를 사용하여 객체 생성 시 초기화를 강제합니다.
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class User {
private String name = "Default Name";
private int age = 18;
}
직렬화/역직렬화 설계 가이드
1. 직렬화/역직렬화가 모두 필요한 DTO 설계
- 권장 어노테이션 조합:
- @NoArgsConstructor, @AllArgsConstructor, @Getter, @Setter
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class UserDTO {
private String name;
private int age;
}
2. 직렬화만 필요한 경우
- 권장 어노테이션 조합:
- @AllArgsConstructor, @Getter
@AllArgsConstructor
@Getter
public class UserResponse {
private String name;
private int age;
}
3. 역직렬화만 필요한 경우
- 권장 어노테이션 조합:
- @NoArgsConstructor, @Getter, @Setter
@NoArgsConstructor
@Getter
@Setter
public class UserRequest {
private String name;
private int age;
}
결론
Lombok은 직렬화/역직렬화 작업을 단순화하는 데 큰 도움을 줍니다. 하지만 올바르지 못한 사용은 예상치 못한 오류를 초래할 수 있습니다. 설계 초기 단계에서 다음을 고려하세요:
- 기본 생성자와 모든 필드 초기화 생성자 조합:
- @NoArgsConstructor와 @AllArgsConstructor를 함께 사용해 역직렬화 가능성을 확보하세요.
- 필드 초기화와 기본값 설정:
- 필드 기본값을 명시적으로 정의하거나 @JsonProperty를 사용해 JSON 데이터 매핑을 명확히 하세요.
- DTO와 엔티티 분리:
- JPA 엔티티와 JSON 직렬화/역직렬화를 위한 객체를 분리해 설계를 간결하게 유지하세요.
728x90
'Spring Boot' 카테고리의 다른 글
[Spring Boot] 로그 파일 생성하기 (0) | 2024.11.30 |
---|---|
[Spring Boot] Slf4j와 Logback (1) | 2024.11.29 |
[Spring Boot] 간단한 실시간 웹소켓 채팅 구현하기 (0) | 2024.11.22 |
[Spring Boot] AccessToken 및 RefreshToken 인증 구현하기 (1) | 2024.11.21 |
[Spring Boot] 스프링 시큐리티 설정 (5) | 2024.11.09 |