상세 컨텐츠

본문 제목

Jackson - ObjectMapper Custom 설정

Spring/JAVA

by Chan.94 2024. 12. 24. 14:47

본문

반응형

Intro

Jackson 라이브러리는 자바에서 JSON 데이터를 처리하기 위한 라이브러리다.

Jackson의 ObjectMapper는 자바 객체와 JSON 데이터 사이의 직렬화와 역직렬화를 담당하는 클래스다.

 

직렬화(Serialization)
일반적으로 직렬화는 객체의 상태를 저장하거나 다른 환경으로 전송 가능한 형태로 변환하는 과정을 의미
직렬화된 형태는 바이트 스트림, JSON, XML 등이 될 수 있다

역직렬화(Deserialization)
직렬화된 데이터(바이트 스트림, JSON, XML 등)를 원래의 데이터 형태(객체, 데이터 구조 등)로 복원하는 과정을 의미

 


ObjectMapper Custom 설정이 왜 필요할까?

기본적으로 스프링부트는 실행이 될 때 ObjectMapper가 설정되어 있는지 확인을 하고 없다면 default 설정으로 ObjectMapper를 만들어준다.

 

데이터를 송수신하는 과정에서 default설정으로 모든 경우를 커버할 수 있을까? 예를 들어 두 가지의 경우를 생각해 보자.

Case(1) 특정 회사와 JSON 통신할 때는 snake_case인데, 내부적으로 camelCase을 사용한다.
Case(2) 객체가 Java 8의 새로운 날짜 및 시간 타입들(LocalDate, LocalTime, LocalDateTime)을 사용하고 있다.

 

default설정으로는 데이터 송수신(직렬화, 역직렬화)을 할 수 없다. 이러한 경우 ObjectMapper를 Custom 하여 사용하면 된다.

  • 성능 개선
    Jackson ObjectMapper는 내부적으로 초기화되는 것들이 많기 때문에 객체 생성이 일반 객체에 비해 30~50배 정도 무겁다.
    ⇒ 싱글톤 방식으로 바꾸면 20~30% 정도 성능 개선 할 수 있다.

  • 중복 & 반복되는 소스 개선
    기본적으로 Jackson 라이브러리는 Java 8의 새로운 날짜 및 시간 타입들(LocalDate, LocalTime, LocalDateTime)을 인식하지 못한다.
    @JsonFormat(pattern = "yyyyMMddHHmmss")
    private LocalDateTime enrDtm;
    ⇒ ObjectMapper에 설정을 추가하여 중복 및 반복되는 소스를 제거한다.

ObjectMapper Configuration 설정

Config.java

@Component
public class JacksonConfig {

    private String dateFormat = "yyyyMMdd";
    private String timeFormat = "HHmmss";
    private String datetimeFormat = "yyyyMMddHHmmss";
    
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategies.SnakeCaseStrategy());
        
        //사용자정의 
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
        simpleModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(timeFormat)));
        simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(datetimeFormat)));
        simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(dateFormat)));
        simpleModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(timeFormat)));
        simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(datetimeFormat)));
        
        objectMapper.registerModule(new Jdk8Module());
        objectMapper.registerModule(simpleModule);
        
        return objectMapper;
    }
}
  • 필드가 없는 Object를 처리하는 방식 결정
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
  • Default 값 : true
  • false : 빈 객체를 허용한다.
  • JSON 데이터에 존재하지 않는 속성이 객체에 존재할 때 어떻게 처리할지를 결정
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  • Default 값 : true
  • false : 무시한다.
  • Property Naming 전략 결정
objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategies.SnakeCaseStrategy());
  • Default : null
    Java 객체 필드 이름과 JSON 속성 이름이 동일하게 매핑된다.
  • Java 8의 새로운 날짜 및 시간 타입들(LocalDate, LocalTime, LocalDateTime) 설정
//사용자정의 
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
simpleModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(timeFormat)));
simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(datetimeFormat)));
simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(dateFormat)));
simpleModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(timeFormat)));
simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(datetimeFormat)));
        
objectMapper.registerModule(simpleModule);

 

  • SimpleModule은 Jackson의 ObjectMapper와 함께 사용되는 확장 모듈로, 사용자 정의 직렬화(Serialization) 및 역직렬화(Deserialization) 로직을 추가할 수 있다.
  • 기본적으로 Jackson 라이브러리는 Java 8의 새로운 날짜 및 시간 타입들(LocalDate, LocalTime, LocalDateTime)을 인식하지 못하기 때문에 해당 타입들을 JSON으로 직렬화하거나 JSON에서 역직렬화할 때 문제가 발생할 수 있다.

마무리

각자 상황을 고려하여 ObjectMapper를 설정하면 된다.

다음글에서 ObjectMapper를 이용하여 직렬화, 역직렬화 과정을 테스트해 보고자 한다.

그 과정에서 readValue(), writeValue(), JsonNode, ObjectNode의 사용법에 대해서 정리해 보겠다.

 

ObjectMapper 사용법 (readValue, writeValue, JsonNode, ObjectNode)

 

Jackson - ObjectMapper 사용법 (readValue, writeValue, JsonNode, ObjectNode)

Intro이전글에서 ObjectMapper 설정에 대해 정리하였다. 이번글에서는 ObjectMapper를 사용법에 대해 정리해보고자 한다.  Jackson - ObjectMapper Custom 설정IntroJackson 라이브러리는 자바에서 JSON 데이터를

fvor001.tistory.com

 

반응형

관련글 더보기

댓글 영역

>