【问题标题】:Deserializing xml with duplicate nested tags with Jackson使用 Jackson 反序列化带有重复嵌套标签的 xml
【发布时间】:2020-01-29 05:57:30
【问题描述】:

我正在尝试反序列化一些具有相同名称的嵌套属性的 xml,但每个属性的包装器名称都是唯一的。下面是示例 XML。

我尝试过切换包装器和属性名称,但似乎不起作用。

<response>
    <string>
        <item>Sample string.</item>
        <item>Another sample string.</item>
    </string>
    <number>
        <item>123123123</item>
        <item>900912</item>
    </number>
</response>

我正在尝试将上述 XML 反序列化为 List&lt;String&gt;List&lt;Integer&gt; 变量。

【问题讨论】:

    标签: java xml jackson xml-serialization


    【解决方案1】:

    我设法让它创建了一对或包装 ArrayLists 作为内部类:

    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
    import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
    import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
    
    @JacksonXmlRootElement(localName="response")
    public class ResponseObjectList implements Serializable {
    
        @JacksonXmlProperty(localName = "string")
        private StringArrayListContainer string;
    
        @JacksonXmlProperty(localName = "number")
        private IntegerArrayListContainer number;
    
        public ResponseObjectList() {
            super();
        }
    
        public ResponseObjectList(List<String> stringItems, List<Integer> intItems) {
            super();
            this.string = new StringArrayListContainer(stringItems);
            this.number = new IntegerArrayListContainer(intItems);
        }
    
        public StringArrayListContainer getString() {
            return string;
        }
    
        public void setString(StringArrayListContainer string) {
            this.string = string;
        }
    
        public IntegerArrayListContainer getNumber() {
            return number;
        }
    
        public void setNumber(IntegerArrayListContainer number) {
            this.number = number;
        }
    
        public static class StringArrayListContainer extends ArrayListContainer<String>{
    
            public StringArrayListContainer() {
                super();
            }
    
            public StringArrayListContainer(List<String> item) {
                super(item);
            }
    
        }
    
        public static class IntegerArrayListContainer extends ArrayListContainer<Integer>{
    
            public IntegerArrayListContainer() {
                super();
            }
    
            public IntegerArrayListContainer(List<Integer> item) {
                super(item);
            }
    
        }
    
        public static class ArrayListContainer<T extends Serializable>{ 
    
            @JacksonXmlElementWrapper(useWrapping=false)
            @JacksonXmlProperty(localName="item")
            private List<T> item;
    
            public ArrayListContainer(List<T> item) {
                super();
                this.item = item;
            }
    
            public ArrayListContainer() {
                super();
            }
    
            public List<T> getItem() {
                return item;
            }
    
            public void setItem(List<T> item) {
                this.item = item;
            }
    
        }
    
    }
    

    测试看起来不错:

    @Test
        public void test3() throws JsonProcessingException {
            ResponseObjectList response = new ResponseObjectList(
                        Arrays.asList(new String[] {"Sample string.","Another sample string"}),
                        Arrays.asList(new Integer[] {123123123,900912})
                    );
            XmlMapper xmlMapper = new XmlMapper();
            String content = xmlMapper.writeValueAsString(response);
            this.logger.debug("content: " + content);
            // content: <response xmlns=""><string><item>Sample string.</item><item>Another sample string</item></string><number><item>123123123</item><item>900912</item></number></response>
        }
    
        @Test
        public void test4() throws JsonParseException, JsonMappingException, IOException {
            String xml = 
                    "<response>"
                    + "<string>"
                    + "<item>Sample string.</item>"
                    + "<item>Another sample string</item>"
                    + "</string>"
                    + "<number>"
                    + "<item>123123123</item>"
                    + "<item>900912</item>"
                    + "</number>"
                    + "</response>";
    
            XmlMapper xmlMapper = new XmlMapper();
            ResponseObjectList object = xmlMapper.readValue(xml, ResponseObjectList.class);
            Assert.assertFalse(object.getString().getItem().isEmpty());
            Assert.assertFalse(object.getNumber().getItem().isEmpty());
        }
    

    我使用Lists 代替ArrayLists 来进行包装和测试

    【讨论】:

      【解决方案2】:

      对于带有JacksonXmlElementWrapper 注释的2.9.9 版本的简单POJO 可以按预期工作:

      class Response {
      
          @JacksonXmlElementWrapper(localName = "string")
          private List<String> strings;
      
          @JacksonXmlElementWrapper(localName = "number")
          private List<Integer> numbers;
      
          // getters, setters
      }
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-13
      • 1970-01-01
      • 2015-05-19
      • 2021-12-14
      • 1970-01-01
      • 2015-03-09
      • 1970-01-01
      • 2021-10-09
      相关资源
      最近更新 更多