首页 > 解决方案 > 使用没有注释的杰克逊将列表序列化为xml?

问题描述

我正在寻找一种方法来(反)序列化List项目而不使用杰克逊中的注释。这可能吗?到目前为止,我正在尝试将<item>-tag 替换为告诉项目类别的标签,但无济于事。即使这可行,我也不确定 Jackson 是否会提供一种方法来处理这些标签信息。

为了更好地说明我的目标,这里有一个示例:

public class JacksonTest {

    private static class ListElement {
        private boolean value;
        // getters, setters, constructors omitted
    }

    @Test
    public void testDeSerialization() throws Exception {
        final List<ListElement> existing = Arrays.asList(new ListElement(true));
        final ObjectMapper mapper = new XmlMapper();
        final JavaType listJavaType = mapper.getTypeFactory().constructCollectionType(List.class, ListElement.class);
        final String listString = mapper.writerFor(listJavaType).writeValueAsString(existing);
        System.out.println(listString);
        // "<List><item><value>true</value></item></List>"
    }

}

因此,结果是<List><item><value>true</value></item></List>,虽然我希望将<item>-tag 替换为(限定的)类名或提供type-attribute。当然,如果杰克逊没有办法处理这个类名,即使这样也无济于事。

我在这里走到了死胡同还是有路要走?

标签: javaxmlgenericscollectionsjackson

解决方案


您可以定义自己的 JsonSerializer(也用于 XML)并将其添加到 JacksonXmlModule。

ToXmlGenerator 有一个 setNextName 函数,允许您覆盖默认项目名称

private class MyListSerializer extends JsonSerializer<List> {
    @Override
    public void serialize(List list, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {
        for (Object obj : list) {
            if (jsonGenerator instanceof ToXmlGenerator) {
                ToXmlGenerator xmlGenerator = (ToXmlGenerator) jsonGenerator;
                String className = obj.getClass().getSimpleName();
                xmlGenerator.setNextName(new QName(className));
            }
            jsonGenerator.writeObject(obj);
            // this is overridden at the next iteration
            // and ignored at the last
            jsonGenerator.writeFieldName("dummy");
        }
    }

    @Override
    public Class<List> handledType() {
        return List.class;
    }
}

@Test
public void testDeSerialization() throws Exception {
    final List<ListElement> existing = Arrays.asList(new ListElement(true));
    JacksonXmlModule module = new JacksonXmlModule();
    module.addSerializer(new MyListSerializer());
    final ObjectMapper mapper = new XmlMapper(module);
    final JavaType listJavaType = mapper.getTypeFactory().constructCollectionType(List.class, ListElement.class);
    final ObjectWriter writer = mapper.writerFor(listJavaType);
    final String listString = writer.writeValueAsString(existing);
    System.out.println(listString);
    // "<List><ListElement><value>true</value></ListElement></List>"
}

推荐阅读