首页 > 解决方案 > 使用 Jackson 库将 Java Map 转换为 XML

问题描述

如何Map使用 Jackson 将 Java 转换为 XML?

版本:

'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.8'

代码:

import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class MainApp {
    
    public static void main(String[] args) throws JsonProcessingException {

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("key1", "value1");
        map.put("key2", "value2");

        Application app = new Application();
        app.setEntry(map);

        // xml output format
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
        System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(app));

    }
    
    @JacksonXmlRootElement(localName = "headers")
    public static class Application {

        private Map<String, Object> entry;

        public Map<String, Object> getEntry() {
            return Collections.unmodifiableMap(entry);
        }

        public void setEntry(Map<String, Object> entry) {
            this.entry = entry;
        }
    }   
    
}

实际输出:

<?xml version='1.0' encoding='UTF-8'?>
<headers>
  <entry>
    <key1>value1</key1>
    <key2>value2</key2>
  </entry>
</headers>

期望的输出:

<?xml version='1.0' encoding='UTF-8'?>
<headers>
    <entry key="key1">value1</entry>
    <entry key="key2">value2</entry>
</headers>

标签: javaxmljacksonhashmapjackson-dataformat-xml

解决方案


您需要实现自定义序列化程序来编写Map这样的条目。示例实现:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class XmlApp {
    public static void main(String[] args) throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("key1", "value1");
        map.put("key2", "value2");

        Application app = new Application();
        app.setEntry(map);

        // xml output format
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
        System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(app));
    }
}

@JacksonXmlRootElement(localName = "headers")
@JsonSerialize(using = ApplicationJsonSerializer.class)
class Application {

    private Map<String, Object> entry;

    public Map<String, Object> getEntry() {
        return Collections.unmodifiableMap(entry);
    }

    public void setEntry(Map<String, Object> entry) {
        this.entry = entry;
    }
}

class ApplicationJsonSerializer extends JsonSerializer<Application> {

    @Override
    public void serialize(Application value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        ToXmlGenerator xmlGen = (ToXmlGenerator) gen;
        xmlGen.writeStartObject();
        for (Map.Entry<String, Object> entry : value.getEntry().entrySet()) {
            xmlGen.writeObjectFieldStart("entry");
            writeAttributes(xmlGen, entry.getKey());
            xmlGen.writeRaw(entry.getValue().toString());
            xmlGen.writeEndObject();
        }
        xmlGen.writeEndObject();
    }

    private void writeAttributes(ToXmlGenerator gen, String key) throws IOException {
        gen.setNextIsAttribute(true);
        gen.writeFieldName("key");
        gen.writeString(key);
        gen.setNextIsAttribute(false);
    }
}

上面的代码打印:

<?xml version='1.0' encoding='UTF-8'?>
<headers>
  <entry key="key1">value1</entry>
  <entry key="key2">value2</entry>
</headers>

推荐阅读