사용자 도구

사이트 도구


java:jackson

Java Jackson JSON Library

@JsonView

@JsonCreator

public class Customer {
    private String id;
    private String name;
    private String address;
 
    public Customer() {
    }
 
    @JsonCreator
    public Customer(
            @JsonProperty("id") String id, 
            @JsonProperty("fullname") String name,
            @JsonProperty("location") String address) {
        System.out.println("run constructor...");
        this.id = id;
        this.name = name;
        this.address = address;
    }
 
    @Override
    public String toString() {
        return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]";
    }
}

Performance

Config 설정

ObjectMapper objectMapper = new ObjectMapper();
 
objectMapper
  // 모르는 property에 대해 무시하고 넘어간다. DTO의 하위 호환성 보장에 필요하다.
  .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
 
  // ENUM 값이 존재하지 않으면 null로 설정한다. Enum 항목이 추가되어도 무시하고 넘어가게 할 때 필요하다.
  .configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
  // 시간을 timestamp 숫자가 아닌, 문자열로 포맷팅한다. 기본 ISO 포맷
  .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

Bidirectional Relation 양방향 관계

Pretty Print

// 전역설정
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
 
// Writer 당 설정
new ObjectMapper()
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(객체);

setDateFormat 주의

  • simpleDateFormat(), dateFormat()을 설정하면 ObjectMapper가 non-thread-safe 하게 돼 버린다. 하지말고, java.util.Date도 사용하지 말 것.

Hibernate

  • Hibernate 사용시 LazyLoading 문제 해소 모듈
  • Lazy Loading 필드일 경우 그냥 null 처리하고 넘어간다. 그러나 이미 로딩이 돼 있으면 직렬화 한다.
  • Lazy Loading 대상 필드의 값을 가져오는 getter가 존재한다면 @JsonIgnore를 하거나 미리 로딩하지 않으면 다시 Lazy Loading Exception 이 발생한다.
  • 양방향 관계에 대해 Jackson - Bidirectional Relationships JPA Entity 직렬화 방법들 참조
    public class User {
        public int id;
        public String name;
     
        // @JsonBackReference 애노테이션이 붙으면 직렬화를 하지 않는다.
        @JsonBackReference
        public List<Item> userItems;
    }
     
    public class Item {
        public int id;
        public String itemName;
     
        @JsonManagedReference
        public User owner;
    }
    {
     "id":2,
     "itemName":"book",
     "owner":
        {
            "id":1,
            "name":"John"
        }
    }
  • @JsonIdentityInfo 사용시에는 양방향 관계에서 Entity Id 만 직렬화해준다.

@JsonRawValue

@JsonInclude

JsonNodeFactory

  • JsonNodeFactory.instance.objectNode() 를 통해 원하는 형태의 JSON 을 생성할 수 있다.
JsonNodeFactory.instance.objectNode().put("id", 123L)
            .put("name", "JSONNODE")
            .put("age", 12)
            .toString();

Java 8

  • Jackson 2 까지는 다음과 같이 모듈들을 추가해줘야 하며 Jackson 3 부터는 Java 8이 필수라서 기본 지원이 된다.
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
// Up to Jackson 2.9: (but not with 3.0)
ObjectMapper mapper = new ObjectMapper()
   .registerModule(new ParameterNamesModule())
   .registerModule(new Jdk8Module())
   .registerModule(new JavaTimeModule()); // new module, NOT JSR310Module
  • SerializationFeature.WRITE_DATES_AS_TIMESTAMPS: false 설정이 있어야만 LocalDateTime 등을 ISO_LOCAL_DATE_TIME format 등으로 직렬화한다.

Jackson 2.10 부터 ObjectMapper 생성 방식 변경됨

JsonMapper objectMapper = JsonMapper.builder()
    .addModules(new ParameterNamesModule(), new Jdk8Module(), new JavaTimeModule())
    // 모르는 property 를 역직렬화 할 때 오류없이 무시하게 한다.
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    // 모르는 ENUM 값을 역직렬화 할 때 null로 취급하게 한다.
    .configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true)
    // 시간 관련 객체(LocalDateTime, java.util.Date)를 직렬화 할 때 timestamp 숫자값이 아닌 포맷팅 문자열로 한다.
    .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
    // 숫자를 문자로 직렬화하기, BigDecimal 보호?
    .enable(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS)
    .defaultTimeZone(TimeZone.getDefault())
    .defaultLocale(Locale.getDefault())
    .build();

Java 16 Record

참고

java/jackson.txt · 마지막으로 수정됨: 2023/10/04 14:47 저자 kwon37xi