I am using Jackson (2.1.1) for JSON serialization/deserialization. I have an existing class with JAXB annotations. Most of these annotations are correct and can be used as-is with jackson. I am using mix-ins to slightly alter the deserialization/serialization of these classes.
In my ObjectMapper constructor I do the following:
setAnnotationIntrospector(AnnotationIntrospector.pair(
new JacksonAnnotationIntrospector(),
new JaxbAnnotationIntrospector(getTypeFactory())));
Based on the above, the Jackson annotations have precedence over Jaxb, because of the order of the introspectors. This is based on the Jackson Jaxb docs. For fields that I want ignored, adding @JsonIgnore
to the field in the mix-in is working fine. There are a couple of fields that are marked as @XmlTransient
in the existing classes that I do not want ignored. I have tried add @JsonProperty
to the field in the mix-in, but it doesn't seem to work.
Here is the original class:
public class Foo {
@XmlTransient public String getBar() {...}
public String getBaz() {...}
}
Here is the mix-in:
public interface FooMixIn {
@JsonIgnore String getBaz(); //ignore the baz property
@JsonProperty String getBar(); //override @XmlTransient with @JsonProperty
}
Any idea how to resolve this without modifying the original class?
I also tested adding @JsonProperty to the members instead of using mix-ins:
public class Foo {
@JsonProperty @XmlTransient public String getBar() {...}
@JsonIgnore public String getBaz() {...}
}
I seem to get the same behavior as I did with the mix-in. Unless @XmlTransient is removed, the property is ignored.
The issue is that the AnnotationIntrospectorPair.hasIgnoreMarker()
method basically ignores the @JsonProperty
if either introspector detects an ignore marker:
public boolean hasIgnoreMarker(AnnotatedMember m) {
return _primary.hasIgnoreMarker(m) || _secondary.hasIgnoreMarker(m);
}
ref: github
A workaround is to subclass the JaxbAnnotationIntrospector
to get the desired behavior:
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);
}
}
}
Then just use the CustomJaxbAnnotationIntrospector
in the AnnotationIntrospectorPair
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With