Jackson 라이브러리 사용시 주의점

rooni97·2022년 10월 4일
0

사전 지식

  • 직렬화: 자바 객체를 바이트로 변환하는 기술
    • Getter, Object To Json
  • 역직렬화: 바이트를 자바 객체로 변환하는 기술
    • 기본 생성자(따라서 불변 객체 불가능), Json To Object

직렬화 - 응답 값으로 자바 객체를 전달할 때 objectMapper가 byte로 변환이 작동, 이 때 Getter가 필요
역직렬화 - 요청 값으로 들어오는 JSON이 자바 객체로 변환이 작동, 이 때 리플렉션이 사용되면서 객체를 생성하기 때문에 기본 생성자가 필수

Json 변환 라이브러리 Jackson의 특징

String dtoToJson = new ObjectMapper().writeValueAsString(dto);
  • Jackson은 객체 필드를 읽을 때 Getter를 통해 접근한다.
  • ObjectMapper가 객체를 Json으로 변환하는데.. @Getter 가 없으면?
    → Getter가 없으니 값에 접근을 못하고 DTO에 값을 채워주지 못하니 Json이 빈 값 {} 으로 나오게 된다.

내가 겪은 오류

@Slf4j
@ControllerAdvice
public class ExceptionController {

	@ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MyCustomException.class)
    @ResponseBody
    public ErrorResponse invalidRequestHandler(MyCustomException e) {
    
        return new ErrorResponse("400", "잘못된 요청입니다");
    }
    
    ...
    
}    
@RequiredArgsConstructor
public class ErrorResponse {

    private final String code;
    private final String message;
}
  • 예상: MyCustomException을 타고 들어와 Json 형태로 ErrorResponse를 반환
  • 실제: 테스트 코드 실행 결과 응답 바디에 {} 빈 값만 나옴.
@Getter // 추가
@RequiredArgsConstructor
public class ErrorResponse {

    private final String code;
    private final String message;
}
  • @Getter 를 추가해주면 정상적으로 출력된다
{"code":"400","message":"잘못된 요청입니다"}

참고) 자바 리플렉션과 Jackson에 관한 자료

리플렉션 정리

  • 리플렉션은 동적으로 객체를 생성해서 무조건 기본 생성자가 있어야함
  • 인자가 있는 생성자는 인자 정보를 못가져옴
  • 기본 생성자로 객체 생성 → 리플렉션 API로 필드 값 채움

번외

  • JPA 엔티티가 기본 생성자를 필수로 요구하는 것과도 관련
  • 결론: JPA에서 불변 객체를 설계하고 싶지만 생성자를 사용해야할 때
    → 기본 생성자는 필수라 private or protected으로 막는 것이 최선
    → 리플렉션은 접근 제어자의 영향을 안받는다

0개의 댓글