사용자 도구

사이트 도구


java:jackson

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
java:jackson [2018/08/09 12:16]
kwon37xi
java:jackson [2023/10/04 14:47] (현재)
kwon37xi
줄 1: 줄 1:
 ====== Java Jackson JSON Library ====== ====== Java Jackson JSON Library ======
   * [[java:jackson:jsonfilter|Jackson JsonFilter]]   * [[java:jackson:jsonfilter|Jackson JsonFilter]]
 +  * [[java:jackson:squiggly|Squiggly]]
   * [[http://www.baeldung.com/jackson|Jackson Tutorial]]   * [[http://www.baeldung.com/jackson|Jackson Tutorial]]
   * [[http://www.baeldung.com/jackson-ignore-properties-on-serialization|Jackson Ignore Properties on Marshalling]]   * [[http://www.baeldung.com/jackson-ignore-properties-on-serialization|Jackson Ignore Properties on Marshalling]]
줄 19: 줄 20:
   * Spring 4.1 부터 ''@JsonView'', [[https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/converter/json/MappingJacksonValue.html|Spring MappingJacksonViewValue]] 지원   * 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://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 ===== ===== @JsonCreator =====
   * 해당 클래스 JSON 문자열을 받아서 객체를 생성할 때 변환기를 직접 만들고자 할 때 구현한다.   * 해당 클래스 JSON 문자열을 받아서 객체를 생성할 때 변환기를 직접 만들고자 할 때 구현한다.
   * [[https://fasterxml.github.io/jackson-annotations/javadoc/2.7/com/fasterxml/jackson/annotation/JsonCreator.html|@JsonCreator]]   * [[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]] 
 +<code java> 
 +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 + "]"; 
 +    } 
 +
 +</code>
 ===== Performance ===== ===== Performance =====
   * [[http://wiki.fasterxml.com/JacksonBestPracticesPerformance|Jackson Best Practice Performance]]   * [[http://wiki.fasterxml.com/JacksonBestPracticesPerformance|Jackson Best Practice Performance]]
줄 31: 줄 58:
 ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
  
-// 모르는 property에 대해 무시하고 넘어간다. DTO의 하위 호환성 보장에 필요하다. +objectMapper 
-objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);+  // 모르는 property에 대해 무시하고 넘어간다. DTO의 하위 호환성 보장에 필요하다. 
 +  .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  
-// ENUM 값이 존재하지 않으면 null로 설정한다. Enum 항목이 추가되어도 무시하고 넘어가게 할 때 필요하다. +  // ENUM 값이 존재하지 않으면 null로 설정한다. Enum 항목이 추가되어도 무시하고 넘어가게 할 때 필요하다. 
-objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);+  .configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); 
 +  // 시간을 timestamp 숫자가 아닌, 문자열로 포맷팅한다. 기본 ISO 포맷 
 +  .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
 </code> </code>
  
-===== Java 8 설정 ===== 
-  * https://github.com/FasterXML/jackson-modules-java8 
- 
-<code java> 
-ObjectMapper mapper = new ObjectMapper() 
-   .registerModule(new ParameterNamesModule()) 
-   .registerModule(new Jdk8Module()) 
-   .registerModule(new JavaTimeModule()); 
-</code> 
- 
-  * [[https://github.com/joschi/jackson-datatype-threetenbp|Java 7용 310 date time backport Jackson Module]] 
  
 ===== Bidirectional Relation 양방향 관계 ===== ===== Bidirectional Relation 양방향 관계 =====
줄 55: 줄 74:
   * [[https://fasterxml.github.io/jackson-annotations/javadoc/2.6/com/fasterxml/jackson/annotation/JsonIdentityInfo.html|@JsonIdentityInfo]] 동일 ID에 대해 중복 출력 방지   * [[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 직렬화 대상에서 제외   * [[https://github.com/FasterXML/jackson-datatype-hibernate|Jackson Datatype Hibernate]] Hibernate Lazy loading 필드를 Jackson 직렬화 대상에서 제외
 +
 ===== Pretty Print ===== ===== Pretty Print =====
 <code java> <code java>
줄 68: 줄 88:
  
 ===== setDateFormat 주의 ===== ===== setDateFormat 주의 =====
-  Jackson 2 ''ObjectMapper.setDateFormat()'' 으로 ''SimpleDateFormat''을 정할 수 있는데 이 경우 ''SimpleDateFormat''은 Thread Safe 하지 해서 Jackson 이 매번 clone을 서 재생성해서 날짜를 포맷팅한다. +    * **''simpleDateFormat(), dateFormat()''을 설정하면 ''ObjectMapper''가 non-thread-safe 하게 돼 버린다.** 하말고, ''java.util.Date''도 사용하지 말 것. 
-  * 성능 저하 요소가 될 수 있으므로 Java 8 이상에서는 가급적면 ''LocalDateTime'' 등을 사용하는게 좋겠다.+ 
 +===== 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 직렬화 방법들]] 참조<code java> 
 +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; 
 +
 +</code><code json> 
 +
 + "id":2, 
 + "itemName":"book", 
 + "owner": 
 +    { 
 +        "id":1, 
 +        "name":"John" 
 +    } 
 +
 +</code> 
 +  * ''@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]] 
 + 
 +<code java> 
 +JsonNodeFactory.instance.objectNode().put("id", 123L) 
 +            .put("name", "JSONNODE"
 +            .put("age", 12) 
 +            .toString(); 
 +</code> 
 + 
 +===== Java 8 ===== 
 +  * [[https://github.com/FasterXML/jackson-modules-java8|jackson modules java8]] 
 +  * Jackson 2 까지는 다음과 같이 모듈들을 추해줘야 하며 Jackson 3 부터는 Java 8이 필수라서 기본 지원이 된다. 
 + 
 +<code> 
 +<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> 
 +</code> 
 + 
 +<code java> 
 +// 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 
 + 
 +</code> 
 +  * ''SerializationFeature.WRITE_DATES_AS_TIMESTAMPS: false'' 설정이 있어야만 ''LocalDateTime'' 등을 ''ISO_LOCAL_DATE_TIME'' format 등으로 직렬화한다. 
 + 
 +===== Jackson 2.10 부터 ObjectMapper 생성 방식 변경됨 ===== 
 +<code java> 
 +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(); 
 +</code>
  
 +===== 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]]<code java>   * [[http://www.baeldung.com/jackson-serialize-dates|Jackson Date]]<code java>
줄 82: 줄 208:
   * [[https://dzone.com/articles/jackson-annotations-for-json-part-2-serialization|Jackson Annotations for JSON (Part 2): Serialization - DZone Java]]   * [[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.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]]
java/jackson.1533784587.txt.gz · 마지막으로 수정됨: 2018/08/09 12:16 저자 kwon37xi