2012-12-28 78 views
8

我正在使用Jackson(2.1.1)进行JSON序列化/反序列化。我有一个带有JAXB注释的现有类。大多数这些注释都是正确的,可以像Jackson一样使用。我正在使用混入来稍微改变这些类的反序列化/序列化。Jackson Jaxb注释优先 - @JsonProperty重写@XmlTransient

在我ObjectMapper构造我做到以下几点:

setAnnotationIntrospector(AnnotationIntrospector.pair(
       new JacksonAnnotationIntrospector(), 
       new JaxbAnnotationIntrospector(getTypeFactory()))); 

基于上述,杰克逊注解优先于JAXB,因为introspectors的顺序。这是基于Jackson Jaxb docs。对于我想要忽略的字段,将@JsonIgnore添加到混音中的字段工作正常。在我不想忽略的现有类中有几个字段被标记为@XmlTransient。我曾尝试在混音中添加@JsonProperty到该字段,但它似乎不起作用。

原来这里是类:

public class Foo { 
    @XmlTransient public String getBar() {...} 
    public String getBaz() {...} 
} 

这里是混合式:

public interface FooMixIn { 
    @JsonIgnore String getBaz(); //ignore the baz property 
    @JsonProperty String getBar(); //override @XmlTransient with @JsonProperty 
} 

任何想法如何解决这个不修改原班?

我还测试加入到@JsonProperty成员,而不是使用混合插件:

public class Foo { 
    @JsonProperty @XmlTransient public String getBar() {...} 
    @JsonIgnore public String getBaz() {...} 
} 

我似乎获得相同的行为,因为我与混合式一样。除非删除@XmlTransient,否则该属性将被忽略。

回答

7

的问题是,AnnotationIntrospectorPair.hasIgnoreMarker()方法基本上忽略@JsonProperty如果任一内部检查检测到一个忽略标记:

public boolean hasIgnoreMarker(AnnotatedMember m) { 
     return _primary.hasIgnoreMarker(m) || _secondary.hasIgnoreMarker(m); 
    } 

REF:github

一种解决方法是继承JaxbAnnotationIntrospector到得到想要的行为:

public class CustomJaxbAnnotationIntrospector extends JaxbAnnotationIntrospector { 
    public CustomJaxbAnnotationIntrospector(TypeFactory typeFactory) { 
     super(typeFactory); 
    } 

    @Override 
    public boolean hasIgnoreMarker(AnnotatedMember m) { 
     if (m.hasAnnotation(JsonProperty.class)) { 
      return false; 
     } else { 
      return super.hasIgnoreMarker(m); 
     } 
    } 
} 

然后只使用CustomJaxbAnnotationIntrospectorAnnotationIntrospectorPair