2014-12-05 43 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 annotationsthe 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 2015-11-18 22:16:07

+0

@Sloth,我想你可以從findObjectIdInfo方法int返回null他回答。我相信我理解你的用例。 – 2015-11-19 11:09:37

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); 
}