Jersey and Jackson serialization of subclasses does not include extra attributes
In Jersey, when using Jackson for JSON serialization, the extra attributes of an implementing subclass are not included. For example, given the following class structure
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="@class")
@JsonSubTypes({
@JsonSubTypes.Type(value = Foo.class, name = "foo")
}
public abstract class FooBase {
pr开发者_JAVA百科ivate String bar;
public String getBar() {
return bar;
}
public void setBar( String bar ) {
this.bar = bar;
}
}
public class Foo extends FooBase {
private String biz;
public String getBiz() {
return biz;
}
public void setBiz( String biz ) {
this.biz = biz;
}
}
And the following Jersey code
@GET
public FooBase get() {
return new Foo();
}
I get back the following json
{"@class" => "foo", "bar" => null}
But what I actually want is
{"@class" => "foo", "bar" => null, "biz" => null}
Also, in my web.xml I have enabled POJOMappingFeature to solve this issue
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
Edit: Fixed the Java code to have the setters set properly and Foo to not be abstract
It should work as you show; with one possible exception: if you enable JAXB annotations (only), JAXB restrictions mandate that only getter/setter pairs are used to detect properties. So try adding setter for 'biz' and see if that changes it.
This would not occur with Jackson annotations; and ideally not if you combine Jackson and JAXB annotations (I thought Jersey enabled both). If Jackson annotation processing is also enabled, adding @JsonProperty next to 'getBiz' should also do the trick.
Finally unless you need JAXB annotations, you could just revert to using Jackson annotations only -- in my opinion, the main use case for JAXB annotations is if you need to produce both XML and JSON, and use JAXB (via Jersey) for XML. Otherwise they aren't useful with JSON.
Using POJOMappingFeature
you can also annotate your classes with JAXB:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class FooBase {
private String bar;
}
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo extends FooBase {
private String biz;
}
精彩评论