当我只有一个不能更改的接口时,我需要能够从json对象创建javapojo。我希望mixins能帮我实现这一点。我创造了一个混音,希望能工作,但不能让Jackson使用它。
看来jackson忽略了我为接口和实现定义的mixin。如果没有将mixin添加到objectmapper中,测试失败是我所期望的。
下面是显示问题的最简单示例。这些类都在各自的包中。真正的用例要复杂得多,包括接口列表。我用的是Jackson2.10.3。
对我做错了什么有什么建议吗?
提摩太
什么不起作用
接口读取器测试失败,invaliddefinitionexception:无法构造model.level4的示例(与默认构造一样,不存在任何创建者):抽象类型需要Map到具体类型、具有自定义反序列化程序或包含其他类型信息
其次,mixin为name字段定义了一个新标签(nametest),它应该反映在writevalueasstring的输出中。它输出带有标签(名称)原始值的字段。
接口
public interface Level4 {
public Long getId();
public void setId(Long id);
public String getName();
public void setName(String name);
}
实施
public class Level4Impl implements Level4 {
private Long id;
private String name;
@Override
public Long getId() {
return id;
}
@Override
public void setId(Long id) {
this.id = id;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
混合
public abstract class Level4Mixin {
public Level4Mixin(
@JsonProperty("id") Long id,
@JsonProperty("nameTest") String name) { }
}
单元测试
class Level4MixinTest {
private ObjectMapper mapper;
@BeforeEach
void setUp() throws Exception {
mapper = new ObjectMapper();
mapper.addMixIn(Level4.class, Level4Mixin.class);
mapper.addMixIn(Level4Impl.class, Level4Mixin.class);
}
@Test
void test_InterfaceWrite() throws JsonProcessingException {
Level4 lvl4 = new Level4Impl();
lvl4.setId(1L);
lvl4.setName("test");
String json = mapper.writeValueAsString(lvl4);
assertNotNull(json);
assertTrue(json.contains("nameTest"));
}
@Test
void test_InterfaceRead() throws JsonProcessingException {
String json = "{\"id\":1,\"nameTest\":\"test\"}";
assertDoesNotThrow(() -> {
Level4 parsed = mapper.readValue(json, Level4.class);
assertNotNull(parsed);
});
}
@Test
void test_ImplWrite() throws JsonProcessingException {
Level4Impl lvl4 = new Level4Impl();
lvl4.setId(1L);
lvl4.setName("test");
String json = mapper.writeValueAsString(lvl4);
assertNotNull(json);
assertTrue(json.contains("nameTest"));
}
@Test
void test_ImplRead() {
String json = "{\"id\":1,\"nameTest\":\"test\"}";
assertDoesNotThrow(() -> {
Level4Impl parsed = mapper.readValue(json, Level4Impl.class);
assertNotNull(parsed);
});
}
}
2条答案
按热度按时间xqkwcwgp1#
要在序列化对象时向该对象添加属性,可以使用@jsonappend。例如:
以及测试:
同样适用于
test_InterfaceWrite
.将json反序列化为对象的测试不清楚:
班级
Level4Impl
不具有属性nameTest
所以反序列化失败了。如果不想抛出异常,可以配置ObjectMapper
在未知属性上不失败。例如:vyu0f0g12#
首先,您必须让jackson知道它应该示例化接口的哪个子类。你可以通过添加
@JsonTypeInfo
和/或@JsonSubTypes
你在课堂上的混音注解。对于单个子类,以下内容就足够了:对于多个子类,它将更加复杂,并且需要json负载中标识具体类型的额外字段。有关详细信息,请参见jackson多态反序列化。另外值得一提的是,添加类型信息将导致type id字段被写入json。仅供参考。
添加新标签就像为所需属性添加一对getter和setter一样简单。显然是原创的
name
在这种情况下,字段也将写入json。为了改变这种情况,您可能需要将@jsonignore放在getter的subclass或mix-in中。在后一种情况下,所有子类的名称都将被忽略。最后一点:在这种情况下,你应该注册你的混音与超级类型只。
以下是对满足测试要求的类所做的更改:
级别4IMPL
混合
级别4混合更改