[英]Deserialize a Map from JAXB generated XML using Jackson
我需要反序列化使用JAXB生成的一些XML。 由於某些合規性問題,我只需要使用Jackson進行XML解析。 嘗試反序列化具有Map的類時遇到異常
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
at [Source: (StringReader); line: 40, column: 21] (through reference chain: FileConfig["otherConfigs"]->java.util.LinkedHashMap["entry"])
我的代碼如下:
XML檔案:
。 。 。
<fileConfig>
<whetherNotify>false</whetherNotify>
<url>....some location....</url>
<includes>app.log</includes>
<fileType>...some string...</fileType>
<otherConfigs>
<entry>
<key>pathType</key>
<value>1</value>
</entry>
</otherConfigs>
</fileConfig>
。 。 。
FileConfig.java
public class FileConfig implements Serializable {
protected Boolean whetherNotify = false;
protected String url;
protected String includes;
protected FileType fileType;
private Map<String, String> otherConfigs = new HashMap<String, String>();
....getters and setters.....
}
Main.java
public class Main {
.
.
.
.
private static <T> T unmarshallFromXML(String xml, Class<T> parseToClass) throws IOException {
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
xmlMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
xmlMapper.setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
xmlMapper.setDefaultUseWrapper(false);
xmlMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
T parsedObject = xmlMapper.readValue(xml, parseToClass);
return parsedObject;
}
}
請提出一種使用Jackson來成功解析該地圖的方法。
默認情況下, Map
在以下位置序列化為XML
:
...
<key>value</key>
<key1>value1</key1>
...
格式。 沒有entry
元素。 您有兩種選擇:
Map
使用List<Entry>
類型。 Map
類型實現自定義反序列化器。 您需要創建Entry
類:
class Entry {
private String key;
private String value;
// getters, setters, toString
}
並將FileConfig
類中的屬性更改為:
List<Entry> otherConfigs;
請參見以下示例:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class XmlApp {
public static void main(String[] args) throws Exception {
File xmlFile = new File("./test.xml");
XmlMapper xmlMapper = new XmlMapper();
FileConfig fileConfig = xmlMapper.readValue(xmlFile, FileConfig.class);
System.out.println(fileConfig);
}
}
class MapEntryDeserializer extends JsonDeserializer<Map<String, String>> {
@Override
public Map<String, String> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
Map<String, String> map = new HashMap<>();
JsonToken token;
while ((token = p.nextToken()) != null) {
if (token == JsonToken.FIELD_NAME) {
if (p.getCurrentName().equals("entry")) {
p.nextToken();
JsonNode node = p.readValueAsTree();
map.put(node.get("key").asText(), node.get("value").asText());
}
}
}
return map;
}
}
class FileConfig {
protected Boolean whetherNotify = false;
protected String url;
protected String includes;
@JsonDeserialize(using = MapEntryDeserializer.class)
private Map<String, String> otherConfigs;
// getters, setters, toString
}
上面的代碼打印:
FileConfig{whetherNotify=false, url='....some location....', includes='app.log', otherConfigs={pathType1=2, pathType=1}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.