Java 继承和方法重载的Jackson序列化问题
我将Jackson与Jersey+Jetty一起用于我的RESTful应用程序。jackson库是:Java 继承和方法重载的Jackson序列化问题,java,json,serialization,jackson,jersey,Java,Json,Serialization,Jackson,Jersey,我将Jackson与Jersey+Jetty一起用于我的RESTful应用程序。jackson库是:jackson-annoations-2.8.0jackson-core-2.8.9和jackson-databind-2.8.9 我无法让Jackson输出子类的值。它总是输出继承类的值。尽管我明确地提供了具体的对象。这个场景有点难以正确表达,我希望下面的例子能更好地解释它 下面是序列化的类的伪代码: Parent0.java: class Parent0 { protected Chil
jackson-annoations-2.8.0
jackson-core-2.8.9
和jackson-databind-2.8.9
我无法让Jackson输出子类的值。它总是输出继承类的值。尽管我明确地提供了具体的对象。这个场景有点难以正确表达,我希望下面的例子能更好地解释它
下面是序列化的类的伪代码:
- Parent0.java:
class Parent0 { protected Child0 child; public Parent0() {} public Child0 getChild() { return child; } public void setChild(Child0 child) { this.child = child; } }
- Parent1.java:
class Parent1 extends Parent0 {}
- Child0.java:
class Child0 { protected int id; public Child0() {} public void setId(int id) { this.id = id; } public int getId() { return this.id; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Child0 child0 = (Child0) o; return id == child0.id; } @Override public int hashCode() { return Objects.hash(id); } }
- Child1.java:
class Child1 extends Child0 { private String childName; public Child1() {} public String getChildName() { return childName; } public void setChildName(String childName) { this.childName = childName; } }
- 在主控制器内部:
Parent0 p0 = new Parent0(); Child0 c0 = new Child0(); c0.setId(0); p0.setChild(c0); Parent0 p1 = new Parent1(); Child1 c1 = new Child1(); c1.setId(1); c1.setChildName("C1"); p1.setChild(c1); serializeAndPrint(p0); // #1 serializeAndPrint(p1); // #2
#1 Parent0.json
{
child: {
id: 0
}
}
#2 Parent1.json
{
child: {
id: 1
}
}
预期:
#2 Parent1.json
{
child: {
id: 1,
childName: "C1"
}
}
序列化由Jersey框架处理。我用
@products(MediaType.APPLICATION\ujson)
注释我的端点,它基本上负责转换 serializeAndPrint方法的实现是什么?我编写了一个单元测试来重现这个问题:
public class JsonTest {
@Test
public void test() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Parent0 p0 = new Parent0();
Child0 c0 = new Child0();
c0.setId(0);
p0.setChild(c0);
Parent0 p1 = new Parent1();
Child1 c1 = new Child1();
c1.setId(1);
c1.setChildName("C1");
p1.setChild(c1);
System.out.println(mapper.writer(new DefaultPrettyPrinter()).writeValueAsString(p0));
System.out.println(mapper.writer(new DefaultPrettyPrinter()).writeValueAsString(p1));
}
}
输出正是您所期望的:
{
"child" : {
"id" : 0
}
}
{
"child" : {
"id" : 1,
"childName" : "C1"
}
}
看起来Jackson不是正在使用的JSON提供程序(如中所示)。您所说的那些依赖项(库)是不够的。它们只是Jackson的核心依赖项。Jackson确实有一个支持JAX-RS的库,如果您使用Jersey,那么Jackson JAX-RS支持库有一个Jersey包装器 如果您使用的是Jersey 2.x,那么您需要的依赖项是
Jersey media json jackson
。添加依赖项后,应在Jersey应用程序配置(web.xml或ResourceConfig)中注册JacksonFeature
。目前,您可能正在使用其他一些JSON提供程序,但您并不知道。检查是否存在任何其他依赖项。如果你有除Jackson以外的任何其他产品,请将其删除。如果jersey-media-json-jackson
是类路径中唯一的提供者,那么您不需要注册JacksonFeature
,它将默认为使用的提供者
如果您使用的是Jersey 1.x,那么依赖项是Jersey json
。添加依赖项后,需要在应用程序配置中(web.xml的init参数或ResourceConfig中)将com.sun.jersey.api.json.POJOMappingFeature
属性设置为true
注意:如果您手动添加JAR,而不使用Maven这样的依赖关系管理器,那么在计算出您需要的所有JAR时需要做更多的工作,因为
jersey media json jackson
或jersey json
都依赖于其他几个JAR。序列化由jersey框架处理。我用@products(MediaType.APPLICATION\ujson)
注释我的端点,它基本上负责转换。既然你的测试用例通过了,我想这和Jersey转换器有关,而不是Jackson本身。我将编辑我的问题以提供此信息。非常感谢。