Skip to content

Empty tags cause incorrect deserialization of unwrapped lists #469

Closed
@jackson-code1

Description

@jackson-code1

We spotted an issue when trying to deserialize an empty tag followed by a list property.

Beans:

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"middle"})
@XmlRootElement(name = "OuterBean", namespace = "http://jackson.test.model")

public class OuterBean
{
    @XmlElement(name = "Middle", namespace = "http://jackson.test.model")
    public OuterBean.MiddleBean middle;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {"inner1", "inner2"})
    
    public static class MiddleBean
    {
        @XmlElement(name = "Inner1", namespace = "http://jackson.test.model")
        public OuterBean.MiddleBean.InnerBean1 inner1;
        @XmlElement(name = "Inner2", namespace = "http://jackson.test.model")
        private List <OuterBean.MiddleBean.InnerBean2> inner2;

        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "", propOrder = {})
        public static class InnerBean1
        {
            @XmlAttribute(name = "Str")
            public String str;
            
            @XmlElement(name = "InnerBean1Item", namespace = "http://jackson.test.model")
            public List <OuterBean.MiddleBean.InnerBean1.InnerBean1Item> item;
          
            @XmlAccessorType(XmlAccessType.FIELD)
            @XmlType(name = "", propOrder = {})
            public static class InnerBean1Item
            {
                @XmlAttribute(name = "Id")
                protected String id;
            }
        }
        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "", propOrder = {})
        public static class InnerBean2
        {
            @XmlAttribute(name = "Str2")
            public String str2;
        }
    }
}

Test case:

import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;

public class EmptyElementsTest
{
    XmlMapper mapper;

    @Before
    public void before()
    {
        mapper = new XmlMapper();
        mapper.setSerializationInclusion(Include.NON_NULL);
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector());
    }

    @Test
    public void testEmptyElements() throws Exception
    {

        String xmlInput = "<OuterBean xmlns='http://jackson.test.model'>" +
            "  <Middle>" +
            "    <Inner1/>" +
            "    <Inner2 Str2='aaaa'/>" +
            "  </Middle>" +
            "</OuterBean>";

        OuterBean deserializedBean = mapper.readValue(xmlInput, OuterBean.class);
        String actual = mapper.writeValueAsString(deserializedBean);
        System.out.println(actual);
    }
}

Actual output:

<OuterBean xmlns="http://jackson.test.model">
  <Middle>
    <Inner1/>
  </Middle>
</OuterBean>

Expected output:

<OuterBean xmlns="http://jackson.test.model">
  <Middle>
    <Inner1/>
    <Inner2 Str2="aaaa"/>
  </Middle>
</OuterBean>

The problem seems to be related to deserialization, because deserializedBean has the Inner1 field value (populated with null values) but the Inner2 field does not deserialize correctly. (the deserialized Inner2 field is an empty list)

It is worth mentioning, that, if you remove the from the xmlInput or if Inner1 is a non-empty tag with a valid value then the Inner2 field gets deserialized correctly.

Library versions:
jackson-annotations-2.12.3.jar,
jackson-core-2.12.3.jar,
jackson-databind-2.12.3.jar,
jackson-dataformat-xml-2.12.3.jar,
jackson-module-jaxb-annotations-2.12.3.jar,

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions