杰克逊自定义反序列化器仅在列表xml中获取最后一个值

时间:2018-08-13 22:58:03

标签: java jackson deserialization

我有以下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的注释,但是没有解决。

2 个答案:

答案 0 :(得分:0)

似乎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));
}

答案 1 :(得分:-2)

如果仍然有人遇到这个问题,请升级到最新的jackson 2.12.3 版本。 我在 2.11.x 版本中遇到了这个问题。