====== Java Jackson JSON Library ======
* [[java:jackson:jsonfilter|Jackson JsonFilter]]
* [[java:jackson:squiggly|Squiggly]]
* [[http://www.baeldung.com/jackson|Jackson Tutorial]]
* [[http://www.baeldung.com/jackson-ignore-properties-on-serialization|Jackson Ignore Properties on Marshalling]]
* [[https://github.com/FasterXML/jackson-module-afterburner|Jackson module afterburner]] Jackson 직렬화/역직렬화 성능 향상
* [[https://github.com/FasterXML/jackson-datatype-hibernate|Jackson datatype hibernate]] Hibernate 데이터를 JSON으로 변환할 때 Lazy loading으로 인해 발생하는 문제 해결
* [[http://wiki.fasterxml.com/JacksonUpgradeFrom19To20|JacksonUpgradeFrom19To20]]
* [[http://www.cowtowncoder.com/blog/archives/2011/09/entry_461.html|Advanced filtering with Jackson, Json Filters]]
* [[http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html|Every day Jackson usage, part 3: Filtering properties]]
* [[http://www.baeldung.com/jackson-annotations|A Guide to Jackson Annotations]]
* [[http://www.baeldung.com/java-json|JSON in Java]]
===== @JsonView =====
* 객체의 필드를 선별적으로 직렬화 할 수 있다.
* ''@Annotation'' 지옥이 필쳐질 수도 있다.
* [[http://wiki.fasterxml.com/JacksonJsonViews|JacksonJsonViews]]
* [[http://stackoverflow.com/questions/5772304/using-jsonview-with-spring-mvc|Using @JsonView with Spring MVC]]
* Spring 4.1 부터 ''@JsonView'', [[https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/converter/json/MappingJacksonValue.html|Spring MappingJacksonViewValue]] 지원
* [[https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring|Latest Jackson integration improvements in Spring]]
* [[https://www.baeldung.com/jackson-json-view-annotation|Jackson JSON Views | Baeldung]]
===== @JsonCreator =====
* 해당 클래스 JSON 문자열을 받아서 객체를 생성할 때 변환기를 직접 만들고자 할 때 구현한다.
* [[https://fasterxml.github.io/jackson-annotations/javadoc/2.7/com/fasterxml/jackson/annotation/JsonCreator.html|@JsonCreator]]
* [[https://grokonez.com/java/jackson-jsoncreator-example-deserialize-jsoncreator|Jackson @JsonCreator example - Deserialize with @JsonCreator - grokonez]]
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 =====
* [[http://wiki.fasterxml.com/JacksonBestPracticesPerformance|Jackson Best Practice 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 양방향 관계 =====
* [[http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion|Jackson - Bidirectional Relationships]]
* [[https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonIgnoreProperties.html|@JsonIgnoreProperties]]
* [[https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonIdentityInfo.html|@JsonIdentityInfo]] 동일 ID에 대해 중복 출력 방지
* [[https://github.com/FasterXML/jackson-datatype-hibernate|Jackson Datatype Hibernate]] Hibernate Lazy loading 필드를 Jackson 직렬화 대상에서 제외
===== Pretty Print =====
// 전역설정
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// Writer 당 설정
new ObjectMapper()
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(객체);
===== setDateFormat 주의 =====
* **''simpleDateFormat(), dateFormat()''을 설정하면 ''ObjectMapper''가 non-thread-safe 하게 돼 버린다.** 하지말고, ''java.util.Date''도 사용하지 말 것.
===== Hibernate =====
* [[java:hibernate|Hibernate]] 사용시 LazyLoading 문제 해소 모듈
* Lazy Loading 필드일 경우 그냥 null 처리하고 넘어간다. 그러나 이미 로딩이 돼 있으면 직렬화 한다.
* Lazy Loading 대상 필드의 값을 가져오는 getter가 존재한다면 ''@JsonIgnore''를 하거나 미리 로딩하지 않으면 다시 Lazy Loading Exception 이 발생한다.
* [[https://github.com/FasterXML/jackson-datatype-hibernate|jackson-datatype-hibernate]]
* 양방향 관계에 대해 [[https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion|Jackson - Bidirectional Relationships JPA Entity 직렬화 방법들]] 참조
public class User {
public int id;
public String name;
// @JsonBackReference 애노테이션이 붙으면 직렬화를 하지 않는다.
@JsonBackReference
public List- 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 =====
* [[https://www.logicbig.com/tutorials/misc/jackson/json-raw-value.html|Jackson JSON - Using @JsonRawValue to serialize property as it is]]
* String 필드게 JSON 문자열이 저장돼 있을 경우 이를 JSON 으로 간주하고 리턴
* 직렬화에서는 작동하지만 역직렬화에서는 작동하지 않는다.
* [[https://stackoverflow.com/questions/4783421/how-can-i-include-raw-json-in-an-object-using-jackson|java - How can I include raw JSON in an object using Jackson? - Stack Overflow]]
===== @JsonInclude =====
* [[https://www.baeldung.com/jackson-ignore-null-fields|Ignore Null Fields with Jackson | Baeldung]]
* ''@JsonInclude(INclude.NON_NULL)'' : null인경우 아예 렌더링을 하지 않는다.
* [[https://alwayspr.tistory.com/31|[Jackson] JsonInclude 속성에 대해 알아보자.]]
===== JsonNodeFactory =====
* [[https://fasterxml.github.io/jackson-databind/javadoc/2.1.0/com/fasterxml/jackson/databind/node/JsonNodeFactory.html|JsonNodeFactory]]
* ''JsonNodeFactory.instance.objectNode()'' 를 통해 원하는 형태의 JSON 을 생성할 수 있다.
* [[java:json|Java JSON]]
JsonNodeFactory.instance.objectNode().put("id", 123L)
.put("name", "JSONNODE")
.put("age", 12)
.toString();
===== Java 8 =====
* [[https://github.com/FasterXML/jackson-modules-java8|jackson modules java8]]
* Jackson 2 까지는 다음과 같이 모듈들을 추가해줘야 하며 Jackson 3 부터는 Java 8이 필수라서 기본 지원이 된다.
com.fasterxml.jackson.module
jackson-module-parameter-names
com.fasterxml.jackson.datatype
jackson-datatype-jdk8
com.fasterxml.jackson.datatype
jackson-datatype-jsr310
// 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 =====
* [[https://carloschac.in/2021/03/04/jacksonrecords/|💾 Java Records 💿 with Jackson 2.12 | Carlos Chacin]]
* Jackson >= 2.12.0 부터 [[java:16|Java 16]] 레코드 사용가능.
===== 참고 =====
* [[http://www.baeldung.com/jackson-serialize-dates|Jackson Date]]
@JsonFormat
(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
private Date createdAt;
* [[http://www.baeldung.com/jackson-advanced-annotations|More Jackson Annotations]]
* [[http://www.baeldung.com/jackson-annotations|Jackson Annotation Examples | Baeldung]]
* [[http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion|Jackson - Bidirectional Relationships | Baeldung]]
* [[https://dzone.com/articles/jackson-annotations-for-json-part-2-serialization|Jackson Annotations for JSON (Part 2): Serialization - DZone Java]]
* [[https://www.javacodegeeks.com/2018/01/ignore-unknown-properties-parsing-json-java-jackson-jsonignoreproperties-annotation-example.html|How to ignore unknown properties while parsing JSON in Java - Jackson @JsonIgnoreProperties Annotation Example | Java Code Geeks - 2018]]
* [[https://www.baeldung.com/jackson-serialize-enums|How To Serialize Enums as JSON Objects with Jackson | Baeldung]]
* [[https://www.baeldung.com/jackson-mapping-dynamic-object|Mapping a Dynamic JSON Object with Jackson | Baeldung]]
* [[https://www.baeldung.com/jackson-annotations|Jackson Annotation Examples | Baeldung]]
* [[https://cheese10yun.github.io/jackson-annotation/|Jackson 어노테이션 사용법(1) - Yun Blog]]
* [[https://dzone.com/articles/jackson-json-and-the-proper-handling-of-unknown-fi|Jackson, JSON and the Proper Handling of Unknown Fields in APIs - DZone Java]]
* [[https://www.baeldung.com/jackson-ignore-null-fields|Ignore Null Fields with Jackson | Baeldung]]
* [[https://www.baeldung.com/jackson-field-serializable-deserializable-or-not|Jackson - Decide What Fields Get (De)Serialized | Baeldung]]
* [[https://www.baeldung.com/jackson-deserialization|Getting Started with Deserialization in Jackson | Baeldung]]