【问题标题】:Deserialize a Map with custom entry names using Jackson XML使用 Jackson XML 反序列化具有自定义条目名称的 Map
【发布时间】:2020-10-10 15:18:36
【问题描述】:

我有一个XML 文档要用Jackson 反序列化:

<root>
  <properties>
    <property>
      <key>k1</key>
      <value>v1<value>
    </property>
  </properties>
</root>

如您所见,/root/properties 看起来非常像一张地图,每个/root/properties/property 都类似于Map.Entry

有没有办法创建一个 POJO 将其反序列化为一个 Map&lt;String, String&gt; 不需要自定义反序列化器?

我希望得到类似以下的东西,但它没有用:

@JacksonXmlRootElement(localName = "root")
public class Root {
  @JacksonXmlElementWrapper(localName = "properties")
  public Map<String, String> properties;
}

我从中得到的错误是:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token

【问题讨论】:

    标签: xml jackson deserialization xml-deserialization jackson-dataformat-xml


    【解决方案1】:

    可以使用JsonAnySetter注解:

    import com.fasterxml.jackson.annotation.JsonAnySetter;
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import com.fasterxml.jackson.dataformat.xml.XmlMapper;
    import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
    
    import java.io.File;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    
    public class XmlMapperApp {
    
        public static void main(String... args) throws Exception {
            File xmlFile = new File("./resource/test.xml").getAbsoluteFile();
    
            XmlMapper mapper = XmlMapper.xmlBuilder().build();
            Root root = mapper.readValue(xmlFile, Root.class);
            System.out.println(root.getProperties());
        }
    }
    
    @JacksonXmlRootElement(localName = "root")
    class Root {
    
        @JsonIgnore
        private Map<String, String> properties = new LinkedHashMap<>();
    
        @JsonAnySetter
        public void setAllProperties(String value, List<Map<String, String>> xmlProperties) {
            if (xmlProperties == null) {
                return;
            }
            this.properties = xmlProperties.stream().reduce(new LinkedHashMap<>(), (l, r) -> {
                l.put(r.get("key"), r.get("value"));
                return l;
            });
        }
    
        public Map<String, String> getProperties() {
            return properties;
        }
    }
    

    以上代码打印为XML:

    {k1=v1}
    

    【讨论】:

      猜你喜欢
      • 2017-03-02
      • 1970-01-01
      • 2020-01-14
      • 1970-01-01
      • 1970-01-01
      • 2020-05-27
      • 2017-01-10
      • 2019-02-08
      • 2016-02-12
      相关资源
      最近更新 更多