如何将动态 JSON 属性 映射到固定 POJO 字段
How to map a dynamic JSON property to a fixed POJO field
我有一些 json 我想解析成 pojo
{
"groups": [
{
"g1": [
1,2,5,6,7
]
},
{
"g2": [
2,3,48,79
]
}
]
}
当然,g1
和 g2
是标识符,所以我认为 pojos 会像
class Container {
List<Group> groups;
}
class Group {
String id;
List<Integer> values;
}
所以归结为这个问题:How to use jackson to map a json-属性 to the pojo?
可以使用添加了 JsonDeserialize 注释的自定义反序列化器来解析这种结构。
POJO
public static class Container {
private List<Group> groups;
public List<Group> getGroups() {
return groups;
}
public void setGroups(List<Group> groups) {
this.groups = groups;
}
@Override
public String toString() {
return String.format("Container [groups=%s]", groups);
}
}
@JsonDeserialize(using=CustomDeserializer.class)
public static class Group {
String id;
List<Integer> values;
@Override
public String toString() {
return String.format("Group [id=%s, values=%s]", id, values);
}
}
反序列化器,注意使用 ObjectMapper.readTree 而不是使用低级 JsonParser API...
public static class CustomDeserializer extends JsonDeserializer<Group> {
@Override
public Group deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
Group group = new Group();
ObjectNode objectNode = new ObjectMapper().readTree(jp);
// assume only a single field...
Entry<String, JsonNode> field = objectNode.fields().next();
group.id = field.getKey();
// there might be a nicer way to do this...
group.values = new ArrayList<Integer>();
for (JsonNode node : ((ArrayNode)field.getValue())) {
group.values.add(node.asInt());
}
return group;
}
}
测试
public static void main(String[] args) throws Exception {
String json = "{\"groups\": [{\"g1\":[1,2,5,6,7]},{\"g2\": [2,3,48,79]}]}";
JsonFactory f = new JsonFactory();
JsonParser jp = f.createParser(json);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(jp, Container.class));
}
输出
Container [groups=[Group [id=g1, values=[1, 2, 5, 6, 7]], Group [id=g2, values=[2, 3, 48, 79]]]]
我有一些 json 我想解析成 pojo
{
"groups": [
{
"g1": [
1,2,5,6,7
]
},
{
"g2": [
2,3,48,79
]
}
]
}
当然,g1
和 g2
是标识符,所以我认为 pojos 会像
class Container {
List<Group> groups;
}
class Group {
String id;
List<Integer> values;
}
所以归结为这个问题:How to use jackson to map a json-属性 to the pojo?
可以使用添加了 JsonDeserialize 注释的自定义反序列化器来解析这种结构。
POJO
public static class Container {
private List<Group> groups;
public List<Group> getGroups() {
return groups;
}
public void setGroups(List<Group> groups) {
this.groups = groups;
}
@Override
public String toString() {
return String.format("Container [groups=%s]", groups);
}
}
@JsonDeserialize(using=CustomDeserializer.class)
public static class Group {
String id;
List<Integer> values;
@Override
public String toString() {
return String.format("Group [id=%s, values=%s]", id, values);
}
}
反序列化器,注意使用 ObjectMapper.readTree 而不是使用低级 JsonParser API...
public static class CustomDeserializer extends JsonDeserializer<Group> {
@Override
public Group deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
Group group = new Group();
ObjectNode objectNode = new ObjectMapper().readTree(jp);
// assume only a single field...
Entry<String, JsonNode> field = objectNode.fields().next();
group.id = field.getKey();
// there might be a nicer way to do this...
group.values = new ArrayList<Integer>();
for (JsonNode node : ((ArrayNode)field.getValue())) {
group.values.add(node.asInt());
}
return group;
}
}
测试
public static void main(String[] args) throws Exception {
String json = "{\"groups\": [{\"g1\":[1,2,5,6,7]},{\"g2\": [2,3,48,79]}]}";
JsonFactory f = new JsonFactory();
JsonParser jp = f.createParser(json);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(jp, Container.class));
}
输出
Container [groups=[Group [id=g1, values=[1, 2, 5, 6, 7]], Group [id=g2, values=[2, 3, 48, 79]]]]