我有Jackson mixin和继承的问题.我有两个目标类,父母和孩子.对于这两个目标类,我已经定义了两个没有继承关系的MixIn类(接口).我还测试了一个MixIn接口扩展了另一个,但结果没有差异.当J
现在的问题是,在序列化子类的对象时,有什么方法可以指示Jackson只使用子类的mixin定义?是的,我想保留两个单独的用例的mixin定义,所以只删除父类mixin映射不会解决我的问题.
示例代码以及下面的预期和实际输出JSON.
环境:
杰克逊版本2.1.4
Tomcat版本7.0.34.0
他们实现的目标类和接口:
public interface TestI { public String getName(); } public interface TestExtendI extends TestI { public Integer getAge(); } public class Test implements TestI { String name; public Test(String name) { this.name = name; } @Override public String getName() { return name; } } public class TestExtend extends Test implements TestExtendI { private Integer age; public TestExtend(String name) { super(name); } public TestExtend(String name, Integer age) { super(name); this.age = age; } @Override public Integer getAge() { return age; } }
Mixins定义
public interface TestMixIn { @JsonProperty("base-name") public String getName(); } public interface TestExtendMixIn { @JsonProperty("ext-name") public String getName(); @JsonProperty("ext-age") public Integer getAge(); }
如果两个mixin都添加到mapper中,则输出JSON为:
{ "base-name": "5", // from parent class mixin definition "ext-age": 50 // from child class mixin defition }
使用mixin for TestI.class注释一切都按预期工作,输出JSON是(这是我想要实现的):
{ "ext-name": "5", // from child class mixin defition "ext-age": 50 // from child class mixin defition }
对象映射器配置
@Provider @Produces(MediaType.APPLICATION_JSON) public class JacksonObjectMapper implements ContextResolver<ObjectMapper> { private ObjectMapper mapper; public JacksonObjectMapper() { mapper = new ObjectMapper(); mapper.addMixInAnnotations(TestI.class, TestMixIn.class); mapper.addMixInAnnotations(TestExtendI.class, TestExtendMixIn.class); } public ObjectMapper getContext(Class<?> type) { return this.mapper; } }
REST api用于处理请求/响应
@Path("api/test/{id}") public class TestRestApi { @GET @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public TestI getTest(@PathParam("id") String id) { TestI ret = new TestExtend(id, 50); return ret; } }
解
正如pgelinas在第一个响应中所描述的那样,解决这个问题的方法是定义应该在子接口中再次由’child’coinin处理的方法.对于上面的示例代码,这将意味着对TestExtendI接口的更改:
public interface TestExtendI extends TestI { public Integer getAge(); // override the method from the parent interface here @Override public String getName(); }
这将解决问题,并且不会向解决方案添加太多样板代码.此外,它不会更改接口契约,因为子接口已经扩展了父接口.
这是一个棘手的问题;您的具体问题的答案是否定的,您无法告诉子类不使用应用于父类的Mixin.但是,这里解决问题的一个简单方法是在TestExtendI接口中重新声明getName()方法.我相信MixIn注释解析不遵循通常的父子覆盖(正常注释的情况),而是更喜欢应用于声明方法的类的MixIn.这可能是杰克逊的错误或设计选择,你总是可以在github填写一个问题.