我想使用单个JSON文件创建多种类型的java对象
我想过以map的形式存储不同类型的java对象,其中key是对象类型的名称,value将是Object本身,如下所示
Field2_AllIn1.json
{
"fetchMapOfStringType": {
"hi": "hello"
},
"fetchMapFieldType": {
"5b0b8a5545424a20487ee2bc": {
"fieldId": "5b0b8a5545424a20487ee2bc",
"value": "25",
"values": [],
"visible": true,
"fieldValidationErrors": [],
"globalValidationErrors": [
{
"fieldValidationId": "5b0b8a5545424a20487ee2bc",
"validationErrorMessage": "this is error"
}
],
"formulaErrors": []
}
}
}
第一个存储一个简单的String类型 第二个存储类型为map的java对象,其中Field是自定义类
public class JsonJacksonAllInOne {
public static void main(String args[]) throws JsonParseException, JsonMappingException, IOException{
try {
// read JSON from a file
Map<String, Object> map = mapper.readValue(
new File("C://json/Field2_AllIn1.json"),
new TypeReference<Map<String, Object>>() {
});
//type String
//String type works fine
Object obj1 = map.get("fetchMapOfStringType");
Map<String, String> mapStringType = (Map<String, String>) obj1;
System.out.println(mapStringType.get("hi"));//this prints hello
//second type ... type casting to object type to objectId and Field map
Map<ObjectId, Field> map1 = (Map<ObjectId, Field>) map.get("fetchMapFieldType");
ObjectId k1 = new ObjectId("5b0b8a5545424a20487ee2bc");
Field f1 = map1.get(k1);
//this code gives value of f1 as null
// this gives class cast exception
// java.util.LinkedHashMap cannot be cast to com.dto.Field
Field f2 = map1.get("5b0b8a5545424a20487ee2bc");
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
您可以在代码中看到注释。 一个给出null other给出了类强制转换异常 我想这个演员没有用 如何获取所需类型的对象 有没有其他方法我可以使用单个JSON文件来创建不同的Java对象,如地图和自定义类列表? ? 我想避免使用不同的JSON文件来创建不同的java对象
答案 0 :(得分:1)
问题在于这一行:
// read JSON from a file
Map<String, Object> map = mapper.readValue(
new File("C://json/Field2_AllIn1.json"),
new TypeReference<Map<String, Object>>() {
});
当您将json作为Map读取时,它将整个json解析为LinkedHashMap(也用于存储顺序,否则也可以使用HashMap)。 之后你不能把它投射到另一个POJO / Beans。
解决方案是将json作为树读取,然后在需要时直接转换为您的POJO以避免不必要的类型转换,这里是更新的代码。
public static void main(String[] args) {
try {
ObjectMapper mapper = new ObjectMapper();
// read JSON from a file as a tree
JsonNode map = mapper.readTree(new File("/home/pratapi.patel/config.json"));
// fetch json node from the tree
JsonNode obj1 = map.get("fetchMapOfStringType");
// convert obj1 (JsonNode) as Map<String, String>
Map<String, String> mapStringType =
mapper.readValue(mapper.treeAsTokens(obj1), new TypeReference<Map<String, String>>() {
});
// prints hello
System.out.println(mapStringType.get("hi"));
// fetch another json node from the tree
JsonNode map1 = map.get("fetchMapFieldType");
// convert map1 (JsonNode) as Map<ObjectId, Field>
Map<ObjectId, Field> mapFieldType = mapper.readValue(mapper.treeAsTokens(map1), new TypeReference<Map<ObjectId, Field>>() {
});
ObjectId k1 = new ObjectId("5b0b8a5545424a20487ee2bc");
Field f1 = mapFieldType.get(k1);
System.out.println(f1);
} catch (IOException e) {
e.printStackTrace();
}
}
此外,由于ObjectId在Map中被用作键,因此它应该是final,并且应该重写equals / hashCode以正常工作。
public class ObjectId {
private final String value;
@JsonCreator
public ObjectId(@JsonProperty("value") String value) {
super();
this.value = value;
}
public String getValue() {
return value;
}
/**
* Auto generated in eclipse
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
/**
* Auto generated in eclipse
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ObjectId other = (ObjectId) obj;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}