在下面的JSON
结构中,fileMetaData
参数具有不同的类型。 Jackson
引发异常com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.XXX.XXX.XXX.FILENAME out of START_ARRAY token
。
示例JSON
负载:
[
{
"fileName": "file_name_1",
"fileMetaData": {
"abcd": "valueabcd",
"xyz": "valuexyz"
}
},
{
"fileName": "file_name_2",
"fileMetaData": [
{
"123": "value123",
"456": "value456"
},
{
"123": "value123-1",
"456": "value456-1"
}
]
},
{
"fileName": "file_name_3",
"fileMetaData": {
"key1": {
"key11": "val11",
"key12": "val22"
},
"key2": "val2"
}
},
{
"fileName": "abc.xyz",
"fileMetaData": null
}
]
如何反序列化?
答案 0 :(得分:2)
通常Jackson
将JSON Array
转换为List
,将JSON Object
转换为Map
。在这种情况下,我们可以使用常规的Object
类型,并将其正确设置。我们只需要检查给定情况下具有哪种类型,并正确地转换为正确的Java
类型即可。参见以下示例:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.List;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
TypeReference<List<Item>> typeReference = new TypeReference<List<Item>>() {
};
List<Item> items = mapper.readValue(jsonFile, typeReference);
items.forEach(item -> {
if (item.isArray()) {
System.out.println("List => " + item.getFileMetaDataAsList());
} else if (item.isObject()) {
System.out.println("Map => " + item.getFileMetaDataAsMap());
}
});
}
}
class Item {
private String fileName;
private Object fileMetaData;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public Object getFileMetaData() {
return fileMetaData;
}
public void setFileMetaData(Object fileMetaData) {
this.fileMetaData = fileMetaData;
}
public boolean isObject() {
return this.fileMetaData instanceof Map;
}
public boolean isArray() {
return this.fileMetaData instanceof List;
}
public Map<String, Object> getFileMetaDataAsMap() {
return (Map<String, Object>) this.fileMetaData;
}
public List<Map<String, Object>> getFileMetaDataAsList() {
return (List<Map<String, Object>>) this.fileMetaData;
}
@Override
public String toString() {
return "Item{" +
"fileName='" + fileName + '\'' +
", fileMetaData=" + fileMetaData +
'}';
}
}
为您的JSON
有效负载打印的内容:
Map => {abcd=valueabcd, xyz=valuexyz}
List => [{123=value123, 456=value456}, {123=value123-1, 456=value456-1}]
Map => {key1={key11=val11, key12=val22}, key2=val2}
答案 1 :(得分:0)
您可以将数据反序列化到JSONNode。您可以使用isArray()方法进行检查,然后将其相应地转换为POJO。
String json = "{ \"f1\" : \"v1\" } ";
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(json);
if(jsonNode .isArray()){
//Do below
}
// acquire reader for the right type
ObjectReader reader = mapper.readerFor(new TypeReference<List<String>>() {
});
// use it
List<String> list = reader.readValue(arrayNode);