Closed
Description
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
Labels
No labels