Jackson Annotation Examples 예제를 적용전, 적용후로 나누어서 정리 해봤습니다.
지속해서 해당 프로젝트를 이어 나아갈 예정이라 깃허브 Start, Watching 버튼을 누르시면 구독 신청받으실 수 있습니다.
테스트 코드도 참고하시면 좋습니다.
2. Jackson Serialization Annotations
직렬화 할 때 Map의 모든 키 - 값 을 표준 일반 속성으로 가져옵니다
@ Getter
@ Builder
public static class ExtendableBean {
public String name ;
private Map <String , String > properties ;
@ JsonAnyGetter
public Map <String , String > getProperties () {
return properties ;
}
}
//적용전
{
"name" : " yun" ,
"properties" : {
"key1" : " value1" ,
"key2" : " value2"
}
}
//적용후
{
"name" : " yun" ,
"key1" : " value1" ,
"key2" : " value2"
}
이름 기반으로 키값이 정해지는것을 어노테이션을 제어
@ Builder
public static class MyBean {
public int id ;
private String name ;
@ JsonGetter ("name" )
public String getTheName () {
return name ;
}
}
//적용전
{
"id" : 1 ,
"theName" : " yun"
}
//적용후
{
"id" : 1 ,
"name" : " yun"
}
@ JsonPropertyOrder ({"name" , "id" })
@ Builder
public static class PropertyOrder {
private long id ;
private String name ;
}
//적용전
{
"id" : 1 ,
"name" : " name"
}
//적용후
{
"name" : " name" ,
"id" : 1
}
@ Builder
public static class RawBean {
public String name ;
@ JsonRawValue
public String json ;
}
//적용전
{
"name" : " yun" ,
"json" : " {\n \" attr\" :false\n }"
}
//적용후
{
"name" : " yun" ,
"json" : {
"attr" : false
}
}
getName @JsonValue 해당 멤버필드가 이름을 통해 직렬화 시킴
public enum TypeEnumWithValue {
TYPE1 (1 , "Type A" ),
TYPE2 (2 , "Type 2" );
private Integer id ;
private String name ;
TypeEnumWithValue (Integer id , String name ) {
this .id = id ;
this .name = name ;
}
@ JsonValue
public String getName () {
return name ;
}
}
//적용전
" TYPE1"
//적용후
" Type A"
@ Builder
@ JsonRootName (value = "user" )
public static class UserWithRoot {
public int id ;
public String name ;
}
//objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE); 반드시 적용해야함
//적용전
{
"id" : 1 ,
"name" : " yun"
}
//적용후
{
"user" : {
"id" : 1 ,
"name" : " yun"
}
}
3. Jackson Deserialization Annotations
JSON key 와 멤버 필드의 이름이 일치하지 않을 경우 사용합니다.
{
"id" :1 ,
"theName" :" My bean"
}
public static class BeanWithCreator {
public int id ;
public String name ;
@ JsonCreator
public BeanWithCreator (
@ JsonProperty ("id" ) int id ,
@ JsonProperty ("theName" ) String name
) {
this .id = id ;
this .name = name ;
}
}
JSON 데이터가 아닌 값을 주입하는데 사용됩니다.
public static class BeanWithInject {
@ JacksonInject
public int id ;
public String name ;
}
Map을 이용해서 유연성있게 Deserialization 합니다.
{
"name" : " My bean" ,
"attr2" : " val2" ,
"attr1" : " val1"
}
public static class ExtendableBean {
public String name ;
private Map <String , String > properties = new HashMap <>();
@ JsonAnySetter
public void setProperties (String key , String value ) {
properties .put (key , value );
}
public String getName () {
return name ;
}
public void setName (String name ) {
this .name = name ;
}
public Map <String , String > getProperties () {
return properties ;
}
}
객체와 맴버필드와 일치하지 않을 경우 유용하게 사용할 수 있습니다.
{
"id" : 1 ,
"name" : " My bean"
}
public static class MyBean {
public int id ;
private String name ;
@ JsonSetter ("name" )
public void setTheName (String name ) {
this .name = name ;
}
public String getTheName () {
return this .name ;
}
}
4. Jackson Property Inclusion Annotations
무시할 속성이나 속성 목록을 표시하는 데 사용됩니다
@ JsonIgnoreProperties ({"id" })
public static class BeanWithIgnore {
public int id ;
public String name ;
}
필드 레벨에서 무시 될 수있는 속성을 표시하는 데 사용됩니다.
public static class BeanWithIgnore {
@ JsonIgnore
public int id ;
public String name ;
}
주석이 달린 형식의 모든 속성을 무시하도록 지정하는 데 사용됩니다
public static class User {
public int id ;
public Name name ;
@ JsonIgnoreType
public static class Name {
public String firstName ;
public String lastName ;
}
}
@ JsonInclude (JsonInclude .Include .NON_NULL )
@ AllArgsConstructor
public static class MyBean {
public int id ;
public String name ;
}
//NON_NULL 사용시 name이 null인 경우에 제외 됩니다.
{
"id" : 1
}
@ JsonAutoDetect (fieldVisibility = JsonAutoDetect .Visibility .ANY )
public static class PrivateBean {
private int id ;
private String name ;
}
// Visibility.ANY 경우 표시
{
"id" : 1 ,
"name" : " yun"
}
5. Jackson Polymorphic Type Handling Annotations
Polymorphic을 통한 직렬화, 비직렬화
@ NoArgsConstructor (access = AccessLevel .PRIVATE )
public static class Zoo {
public Animal animal ;
public Zoo (Animal animal ) {
this .animal = animal ;
}
@ JsonTypeInfo (
use = JsonTypeInfo .Id .NAME ,
include = JsonTypeInfo .As .PROPERTY ,
property = "type" )
@ JsonSubTypes ({
@ JsonSubTypes .Type (value = Dog .class , name = "dog" ),
@ JsonSubTypes .Type (value = Cat .class , name = "cat" )
})
@ Getter
@ NoArgsConstructor (access = AccessLevel .PRIVATE )
public static class Animal {
private String name ;
public Animal (String name ) {
this .name = name ;
}
}
@ JsonTypeName ("dog" )
@ Getter
@ NoArgsConstructor (access = AccessLevel .PRIVATE )
public static class Dog extends Animal {
public double barkVolume ;
public Dog (String name ) {
super (name );
}
}
@ JsonTypeName ("cat" )
@ Getter
@ NoArgsConstructor (access = AccessLevel .PRIVATE )
public static class Cat extends Animal {
boolean likesCream ;
public int lives ;
public Cat (String name ) {
super (name );
}
}
}
{
"animal" : {
"type" : " dog" ,
"name" : " lacy" ,
"barkVolume" : 0
}
}
{
"animal" :{
"name" :" lacy" ,
"type" :" cat"
}
}
6.Jackson General Annotations
날짜 / 시간 값을 직렬화 할 때 포멧팅을 지정합니다
public static class Event {
public String name ;
@ JsonFormat (
shape = JsonFormat .Shape .STRING ,
pattern = "dd-MM-yyyy hh:mm:ss" )
public Date eventDate ;
public Event (String name , Date date ) {
this .name = name ;
this .eventDate = date ;
}
}
//적용전
{
"name" :" party" ,
"eventDate" :1419042600000
}
//적용후
{
"name" : " party" ,
"eventDate" : " 20-12-2014 02:30:00"
}
직렬화, 비 직렬화 될 때 언 래핑 / 병합되어야 하는 값 을 정의하는 데 사용됩니다
public static class UnwrappedUser {
public int id ;
@ JsonUnwrapped
public Name name ;
public UnwrappedUser (int id , Name name ) {
this .id = id ;
this .name = name ;
}
public static class Name {
public String firstName ;
public String lastName ;
public Name (String firstName , String lastName ) {
this .firstName = firstName ;
this .lastName = lastName ;
}
}
}
//적용전
{
"id" : 1 ,
"firstName" : " John" ,
"lastName" : " Doe"
}
//적용후
{
"id" :1 ,
"name" :{
"firstName" :" John" ,
"lastName" :" Doe"
}
}
속성이 serialization / deserialization에 포함될 View 를 나타내는 데 사용됩니다.
public static class Views {
public static class Public {
}
public static class Internal extends Public {
}
}
public static class Item {
@ JsonView (Views .Public .class )
public int id ;
@ JsonView (Views .Public .class )
public String itemName ;
@ JsonView (Views .Internal .class )
public String ownerName ;
public Item (int id , String itemName , String ownerName ) {
this .id = id ;
this .itemName = itemName ;
this .ownerName = ownerName ;
}
}
//적용전
{
"id" :2 ,
"itemName" :" book" ,
"ownerName" :" John"
}
//적용후
{
"id" :2 ,
"itemName" :" book"
}
@JsonManagedReference, @JsonBackReference
객체의 상위 / 하위 관계를 처리 명시하고 무한 순함참조에러를 해결합니다.
public static class ItemWithRef {
public int id ;
public String itemName ;
@ JsonManagedReference
public UserWithRef owner ;
public ItemWithRef (int id , String itemName , UserWithRef owner ) {
this .id = id ;
this .itemName = itemName ;
this .owner = owner ;
}
}
public static class UserWithRef {
public int id ;
public String name ;
@ JsonBackReference
public List <ItemWithRef > itemWithRefs = new ArrayList <>();
public UserWithRef (int id , String name ) {
this .id = id ;
this .name = name ;
}
public void addItem (ItemWithRef item ) {
itemWithRefs .add (item );
}
}
//적용전
// Infinite recursion (StackOverflowError)... 무한 순함참조 에러
//적용후
{
"id" :2 ,
"itemName" :" book" ,
"owner" :{
"id" :1 ,
"name" :" John"
}
}
@ JsonFilter ("myFilter" )
public static class BeanWithFilter {
public int id ;
public String name ;
public BeanWithFilter (int id , String name ) {
this .id = id ;
this .name = name ;
}
}
//적용전
{
"id" :1 ,
"name" :" My bean"
}
//적용후
{
"name" :" My bean"
}
Custom Jackson Annotation
Annotation 직접 정리 할 수 있습니다.
@ CustomAnnotation
public static class BeanWithCustomAnnotation {
public int id ;
public String name ;
public Date dateCreated ;
public BeanWithCustomAnnotation (int id , String name , Date dateCreated ) {
this .id = id ;
this .name = name ;
this .dateCreated = dateCreated ;
}
}
@ Retention (RetentionPolicy .RUNTIME )
@ JacksonAnnotationsInside
@ JsonInclude (JsonInclude .Include .NON_NULL )
@ JsonPropertyOrder ({"name" , "id" , "dateCreated" })
@interface CustomAnnotation {
}
// 적용전
{
"id" : 1 ,
"name" : " My bean" ,
"dateCreated" : null
}
// 적용후, property order 변경, null 값 비 직렬화
{
"name" : " My bean" ,
"id" : 1
}
Disable Jackson Annotation
모든 Jackson annotation 비활성화 하는 방법
@ JsonInclude (JsonInclude .Include .NON_NULL )
@ JsonPropertyOrder ({"name" , "id" })
public static class MyBean {
public int id ;
public String name ;
public MyBean (int id , String name ) {
this .id = id ;
this .name = name ;
}
}
mapper .disable (MapperFeature .USE_ANNOTATIONS ); // 모든 Jackson annotation 비활성화
// MapperFeature.USE_ANNOTATIONS 적용전
{
"id" :1 ,
"name" :null
}
// MapperFeature.USE_ANNOTATIONS 적용후
{
"id" : 1
}