java - 杰克逊自定义反序列化器仅获取列表 xml 中的最后一个值
问题描述
我有以下xml
<root>
<date>112004</date>
<entries>
<entry id = 1>
<status>Active</status>
<person>
<Name>John</Name>
<Age>22</Age>
</person>
</entry>
<entry id = 2>
<status>Active</status>
<person>
<Name>Doe</Name>
<Age>32</Age>
</person>
</entry>
<entry id = 3>
<status>N/A</status>
</entry>
</entries>
我正在使用自定义杰克逊反序列化器来获取值和 pojo 看起来像
@JacksonXmlRootElement(localName="root", namespace="namespace")
类根{私人字符串日期;
@JacksonXmlProperty(localName = "entries", namespace="tns")
private List<Entry> entries;
//getter and setter
}
class Entry {
private String id;
private String status;
private Person person;
//getter and setter
}
反序列化代码看起来像
public class DeSerializer extends StdDeserializer<root>
{
protected DeSerializer() {
super(root.class);
}
@Override
public root deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode nodes = p.readValueAsTree();
ObjectMapper mapper = new ObjectMapper();
List<Entry> entry = mapper.convertValue(nodes.findValues("entry"), new TypeReference<List<Entry>>() {});
}
}
main()
{
XmlMapper x = new XmlMapper();
final SimpleModule module = new SimpleModule("configModule", com.fasterxml.jackson.core.Version.unknownVersion());
module.addDeserializer(root.class, new DeSerializer());
x.registerModule(module);
root r = x.readValue(xmlSource, root.class); /*xmlsource is xml as string*/
}
问题是当我调试时,我总是从 xml 获取条目的最后一个值。所以节点的值(在反序列化器中)是 {"date":"112004","entries":{"entry":{"id":"3","status":"N/A"}}} 和我不确定为什么它不被视为列表。我确实为 List 添加了 unwrapped = false 注释,但没有成功。
解决方案
它似乎readValueAsTree
不支持获取整个集合。
我做了一些没有自定义DeSerializer
的工作。
@JacksonXmlRootElement(localName="root")
public class Root {
@JacksonXmlElementWrapper(useWrapping = true)
private List<Entry> entries;
private String date;
public List<Entry> getEntries() {
return entries;
}
public void setEntries(List<Entry> entries) {
if (this.entries == null){
this.entries = new ArrayList<>(entries.size());
}
this.entries.addAll(entries);
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
class Entry {
private String id;
private String status;
private Person person;
}
class Person {
@JacksonXmlProperty(localName = "Name")
private String name;
@JacksonXmlProperty(localName = "Age")
private String age;
}
然后单元测试:
@Test
void test_xml_XmlMapper() throws Exception {
JacksonXmlModule xmlModule = new JacksonXmlModule();
xmlModule.setDefaultUseWrapper(false);
ObjectMapper xmlMapper = new XmlMapper(xmlModule);
String xmlContent = "your xml file here"
Root bean = xmlMapper.readValue(xmlContent, Root.class);
assertThat(bean.getEntries().size(), Matchers.equalTo(3));
}
推荐阅读
- spring-mvc - 使用 GPC 部署 Spring MVC 应用程序:Cloud SQL、Kubernetes(服务和入口)和带有 Google 托管证书的 HTTP(S) 负载均衡器
- intellij-idea - IntelliJ IDEA 的 JVM 调试器内存视图
- rust - `UnsafeCell` 是 Rust 中的编译器优化障碍吗?
- json - 在 go 中解析自定义 JSON,类型动态确定
- javascript - 单击新图标时,地图图标不会恢复到正常大小
- html - 如何使用标签管理器跟踪与 Facebook 聊天插件的互动?
- css - 如何在移动设备上将 div 内的元素对齐为 2-3 行(响应式)
- go - 无需硬编码类型或将类型信息存储在数组中的类型检查
- reactjs - 使用 CRACO 禁用文件分块
- linux - 如何减去日期