问题
I have a situation where I need to parse an array of JSON objects that are not identical.
So for example:
[
{ "type": "type1", ..... type1 contents .... },
{ "type": "type2", ..... type2 contents .... },
....
{ "type": "type1", ..... type1 contents .... }
]
The number of types is limited and the contents of each type are well can be defined but it is not possible to define a single type of object that will hold the contents.
Is there a way to parse them with Jackson?
P.S. I am trying to avoid writing a custom parser if I can help it.
回答1:
I would use
com.fasterxml.jackson.databind.JsonNode
.
JsonNode parsed = objectMapper
.readValue("[{\"name\": \"a\"},{\"type\":\"b\"}]", JsonNode.class);
This class has tons of utility methods to work with.
Or specific for arrays you can use:
com.fasterxml.jackson.databind.node.ArrayNode
ArrayNode value = objectMapper
.readValue("[{\"name\": \"a\"},{\"type\":\"b\"}]", ArrayNode.class);
EDIT
Sorry, I have misread your question, you can use @JsonTypeInfo
for polymorphic serialization/deserialization:
public static void main(String args[]) throws JsonProcessingException {
//language=JSON
String data = "[{\"type\":\"type1\", \"type1Specific\":\"this is type1\"},{\"type\":\"type2\", \"type2Specific\":\"this is type2\"}]";
ObjectMapper objectMapper = new ObjectMapper();
List<BaseType> parsed = objectMapper.readValue(data, new TypeReference<List<BaseType>>() {});
System.out.println(parsed);
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes(value = {
@JsonSubTypes.Type(value = Type1.class, name = "type1"),
@JsonSubTypes.Type(value = Type2.class, name = "type2")
})
static public abstract class BaseType {
public String type;
}
static public class Type1 extends BaseType {
public String type1Specific;
@Override
public String toString() {
return "Type1{" +
"type1Specific='" + type1Specific + '\'' +
'}';
}
}
static public class Type2 extends BaseType {
public String type2Specific;
@Override
public String toString() {
return "Type2{" +
"type2Specific='" + type2Specific + '\'' +
'}';
}
}
Here are the docs:
https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization
Hope this helps.
And the result would be:
[Type1{type1Specific='this is type1'}, Type2{type2Specific='this is type2'}]
回答2:
We can use List.class to map this JSON Array with different types of objects that hold the content. It will return the List of LinkedHashMaps. Different content will be mapped to LinkedHashMap.
@Test
public void testLoadCustom() {
String json = "[{\"a\":\"A\" } , {\"b\":\"B\" , \"c\":\"C\" } , {\"d\":\"D\" } ]";
try {
List custom = objectMapper.readValue(json, List.class);
System.out.println(custom);
} catch (Exception ex) {
ex.getStackTrace();
}
}
// Output [{a=A}, {b=B, c=C}, {d=D}]
来源:https://stackoverflow.com/questions/60329302/parsing-an-array-of-non-homogeneous-json-objects-with-jackson