问题描述
<root>
<properties>
<property>
<key>k1</key>
<value>v1<value>
</property>
</properties>
</root>
如您所见,/root/properties
非常像一张地图,每个/root/properties/property
都像一个Map.Entry
。
是否有一种无需创建自定义反序列化器即可创建POJO
并将其反序列化为Map<String,String>
的方法?
我希望获得以下类似信息,但没有成功:
@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
解决方法
您可以使用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}