2014-12-05 5 views
2

Я использую Jackson 2.2.3 для сериализации POJO для JSON. Тогда у меня была проблема, что я не мог сериализовать рекурсивные структуры ... Я решил эту проблему, используя @JsonIdentityInfo => отлично работает.Использование @JsonIdentityInfo без аннотаций

Но, я не хочу эту аннотацию на верхней части моего POJO.

Так что мой вопрос: есть ли другая возможность установить поведение по умолчанию моего ObjectMapper, чтобы использовать эту функцию для каждого POJO?

Так что я хочу, чтобы преобразовать эту аннотацию код

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 

к чему-то вроде

ObjectMapper om = new ObjectMapper(); 
om.setDefaultIdentityInfo(ObjectIdGenerators.IntSequenceGenerator.class, "@id"); 

Любые идеи?

ответ

3

Вы можете достичь этого, используя the Jackson mix-in annotations или the Jackson annotation introspector.

Вот пример, показывающий оба метода:

public class JacksonJsonIdentityInfo { 
    @JsonIdentityInfo(
      generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") 
    static class Bean { 
     public final String field; 

     public Bean(final String field) {this.field = field;} 
    } 

    static class Bean2 { 
     public final String field2; 

     public Bean2(final String field2) {this.field2 = field2;} 
    } 

    @JsonIdentityInfo(
      generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id2") 
    static interface Bean2MixIn { 
    } 

    static class Bean3 { 
     public final String field3; 

     public Bean3(final String field3) {this.field3 = field3;} 
    } 

    static class MyJacksonAnnotationIntrospector extends JacksonAnnotationIntrospector { 
     @Override 
     public ObjectIdInfo findObjectIdInfo(final Annotated ann) { 
      if (ann.getRawType() == Bean3.class) { 
       return new ObjectIdInfo(
         PropertyName.construct("@id3", null), 
         null, 
         ObjectIdGenerators.IntSequenceGenerator.class, 
         null); 
      } 
      return super.findObjectIdInfo(ann); 
     } 
    } 

    public static void main(String[] args) throws JsonProcessingException { 
     final Bean bean = new Bean("value"); 
     final Bean2 bean2 = new Bean2("value2"); 
     final Bean3 bean3 = new Bean3("value3"); 
     final ObjectMapper mapper = new ObjectMapper(); 
     mapper.addMixInAnnotations(Bean2.class, Bean2MixIn.class); 
     mapper.setAnnotationIntrospector(new MyJacksonAnnotationIntrospector()); 
     System.out.println(mapper.writeValueAsString(bean)); 
     System.out.println(mapper.writeValueAsString(bean2)); 
     System.out.println(mapper.writeValueAsString(bean3)); 
    }  
} 

Выход:

{"@id":1,"field":"value"} 
{"@id2":1,"field2":"value2"} 
{"@id3":1,"field3":"value3"} 
+0

привет, может быть вы знаете, как получить выход без «@id»? мой вопрос здесь http://stackoverflow.com/questions/33790565/jsonidentityinfo-how-to-not-serialize-id-property – serhii

+0

@Sloth, я предполагаю, что вы можете вернуть null из метода findObjectIdInfo, о котором он отвечает. Я уверен, что понимаю ваш случай использования. –

0

После нескольких месяцев и много исследований, я реализовал свое собственное решение, чтобы сохранить свой домен ясно из Джексона.

public class Parent { 
    private Child child; 
    public Child getChild(){return child;} 
    public void setChild(Child child){this.child=child;} 
} 

public class Child { 
    private Parent parent; 
    public Child getParent(){return parent;} 
    public void setParent(Parent parent){this.parent=parent;} 
} 

Во-первых, вы должны объявить каждого из субъектов двунаправленной связи:

public interface BidirectionalDefinition { 

    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Parent.class) 
    public interface ParentDef{}; 

    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Child.class) 
    public interface ChildDef{}; 

} 

После этого объект картографа может быть автоматически настроен:

ObjectMapper om = new ObjectMapper(); 
Class<?>[] definitions = BidirectionalDefinition.class.getDeclaredClasses(); 
for (Class<?> definition : definitions) { 
    om.addMixInAnnotations(definition.getAnnotation(JsonIdentityInfo.class).scope(), definition); 
} 
Смежные вопросы