Java Jackson:反序列化XML在列表中提供了太多的元素

Java Jackson:反序列化XML在列表中提供了太多的元素,java,xml,jackson,jackson-dataformat-xml,Java,Xml,Jackson,Jackson Dataformat Xml,尝试反序列化XML,如: <?xml version="1.0" encoding="UTF-8"?> <Items> <Item> <Element> <Link uri="urn:1">TestLC</Link> </Element> <Element2> <Link>link<

尝试反序列化XML,如:

<?xml version="1.0" encoding="UTF-8"?>
<Items>
    <Item>
        <Element>
            <Link uri="urn:1">TestLC</Link>
        </Element>
        <Element2>
            <Link>link</Link>
        </Element2>
    </Item>
</Items>

TestLC
链接
使用代码:

@JacksonXmlRootElement(localName = "Items")
@Data
@NoArgsConstructor
public class ItemInfo {

    @JacksonXmlProperty(localName = "Item")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Item> items;

    @Data
    @NoArgsConstructor
    public static class Item {
        @JacksonXmlProperty(localName = "Element")
        private Element element;
    }

    @Data
    @NoArgsConstructor
    public static class Element {
        @JacksonXmlProperty(localName = "Link")
        private String link;
    }

    public static void main(String[] args) throws IOException {
        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<Items>"
                + "    <Item>"
                + "        <Element>"
                + "            <Link uri=\"urn:1\">TestLC</Link>"
                + "        </Element>"
                + "        <Element2>"
                + "            <Link>link</Link>"
                + "        </Element2>"
                + "    </Item>"
                + "</Items>";

        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        ItemInfo itemInfo = xmlMapper.readValue(xml, ItemInfo.class);
        System.out.println(itemInfo.getItems().size());
    }
}
@JacksonXmlRootElement(localName=“Items”)
@资料
@诺尔格构装师
公共类ItemInfo{
@JacksonXmlProperty(localName=“Item”)
@JacksonXmlElementWrapper(useWrapping=false)
私人清单项目;
@资料
@诺尔格构装师
公共静态类项{
@JacksonXmlProperty(localName=“Element”)
私人要素;
}
@资料
@诺尔格构装师
公共静态类元素{
@JacksonXmlProperty(localName=“Link”)
私有字符串链接;
}
公共静态void main(字符串[]args)引发IOException{
字符串xml=“”
+ ""
+ "    "
+ "        "
+“TestLC”
+ "        "
+ "        "
+“链接”
+ "        "
+ "    "
+ "";
XmlMapper XmlMapper=新的XmlMapper();
configure(在未知属性上反序列化feature.FAIL,false);
ItemInfo ItemInfo=xmlMapper.readValue(xml,ItemInfo.class);
System.out.println(itemInfo.getItems().size());
}
}
我希望输出
1
,即
itemInfo
,其中
items
包含一个与单个
标记对应的元素

但是,输出为
2
。不知何故,解析器认为有两个

我不明白这里发生了什么,出了什么问题。例如,如果我删除属性
uri
,结果与预期的一样

itemInfo.getItems()的内容

[ItemInfo.Item(element=ItemInfo.element(link=TestLC)), ItemInfo.Item(元素=null)]


我使用的是
jackson-dataformat-xml
version
2.8.10
您不需要wrapper
ItemInfo
,因为我们可以将其视为
Item
元素的包装器。您可以将代码简化为:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.io.File;
import java.util.Arrays;

public class XmlApp {

  public static void main(String[] args) throws Exception {
    File xmlFile = new File("./resources/test.xml");

    XmlMapper xmlMapper = new XmlMapper();
    xmlMapper.setDefaultUseWrapper(true);
    xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    Item[] itemInfo = xmlMapper.readValue(xmlFile, Item[].class);
    System.out.println(Arrays.toString(itemInfo));
  }
}

class Item {
  @JacksonXmlProperty(localName = "Element")
  private Element element;

  // getters, setters, toString
}

class Element {
  @JacksonXmlProperty(localName = "Link")
  private String link;

  // getters, setters, toString
}
以上代码打印:

[Item{element=Element{link='TestLC'}}]

itemInfo.getItems()中的项目是什么?您可以打印它们吗?
[ItemInfo.Item(element=ItemInfo.element(link=TestLC)),ItemInfo.Item(element=null)]
非常感谢。作品知道我的代码为什么不起作用吗?Jackson中的Bug?@DagR,我不确定这是否是Bug,因为
Element2
可能是个问题。也许当我们将它映射到
Java
中的属性时,它就可以工作了。我更喜欢使用
useWrapping
,因为它需要更少的
POJO
类,我们可以直接使用
List
属性,而不需要额外的包装器。但是您可以尝试从
私有列表项中删除
@JacksonXmlProperty(localName=“Item”)
注释属性。最好先创建
POJO
对象并序列化它们。如果生成的
XML
看起来与要反序列化的负载相同,则很有可能对其进行解析。