Jackson 集合反序列化器接受空 xml 标签

cha*_*iya 5 java xml jackson deserialization

我面临以下问题。

作为 XML Jackson 库的用户,我想知道是否有可能反序列化XML List包含 null 元素。

考虑下面的类:

public class TestJacksonList {

List<String> strings;
List<Integer> integers;
List<Path> paths;

public static final ObjectMapper XML_MAPPER = new XmlMapper()
        .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
        .setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);


public static TestJacksonList parseXml(String content) throws IOException {
    try {
        TestJacksonList testJacksonList = XML_MAPPER.readValue(content, TestJacksonList.class);
        return testJacksonList;
    } catch (IOException e) {
        throw e;
    }
}

public List<String> getStrings() {
    return strings;
}

public List<Path> getPaths() {
    return paths;
}

    public List<Integer> getIntegers() {
        return integers;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望通过以下测试:

public class TestJacksonListTest {

    @Test
    public void should_deserialize_strings_tags() throws IOException {

        // given
        String inputXml = "<xml>" +
                "<strings>" +
                "<string>hello</string>" +
                "<string>world</string>" +
                "<string></string>" +
                "</strings></xml>";

        // when
        TestJacksonList testJacksonList = TestJacksonList.parseXml(inputXml);

        // then --> OK
        Assertions.assertThat(testJacksonList.getStrings()).hasSize(3).containsOnly("hello", "world", "");
    }


    @Test
    public void should_deserialize_integer_tags() throws IOException {

        // given
        String inputXml = "<xml>" +
                "<integers>" +
                "<integer>12</integer>" +
                "<integer></integer>" +
                "<integer>32</integer>" +
                "</integers></xml>";

        // when
        TestJacksonList testJacksonList = TestJacksonList.parseXml(inputXml);

        // then --> KO
        Assertions.assertThat(testJacksonList.getIntegers()).hasSize(3);
    }

    @Test
    public void should_deserialize_path_tags() throws IOException {

        // given
        String inputXml = "<xml>" +
                "<paths>" +
                "<path>hello</path>" +
                "<path>world</path>" +
                "<path></path>" +
                "</paths></xml>";

        // when
        TestJacksonList testJacksonList = TestJacksonList.parseXml(inputXml);

        // then --> KO
        Assertions.assertThat(testJacksonList.getPaths()).hasSize(3);
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是我注意到的事情:

  • String列表表示包含空元素是可以的。它稍后被解释为空字符串(因为Jackson使用特定的StringCollectionDeserializer
  • 其他列表类型使用CollectionDeserializer不接受空标签的通用。它会触发异常:

    com.fasterxml.jackson.databind.JsonMappingException:无法从 START_OBJECT 令牌中反序列化 java.lang.Integer 实例 [来源:java.io.StringReader@6fe7aac8;行:1,列:46](通过参考链:com.altirnao.migrationtools.core.model.configuration.TestJacksonList["integers"]->java.util.ArrayList 1

我查了一下,DeserialisationFeature但似乎没有一个与我的情况相符。

当标签为空时,我希望List包含null.

我们可能会争辩说,将空标签放入列表容器标签中是没有意义的,但是XML我想要解析的内容被倾向于这样做的非技术用户修改了。

最后但并非最不重要的一点是,如果标签没有嵌套,它可以为空,即表示路径字段的标签可以为空,并且将被反序列化为 null。我希望在列表容器中也有同样的效果。