java - 如何将动态 JSON 属性映射到固定 POJO 字段

标签 java json jackson json-deserialization

我有一些 json 想要解析成 pojo

{
  "groups": [
    {
      "g1": [
        1,2,5,6,7
      ]
    },
    {
      "g2": [
        2,3,48,79
      ]
    }
  ]
}   

当然,g1g2是标识符,所以我想象的pojos会是这样的

class Container {
    List<Group> groups;
}

class Group {
    String id;
    List<Integer> values;
}

所以它归结为这个问题:如何使用 jackson 将 json-property 映射到 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]]]]

关于java - 如何将动态 JSON 属性映射到固定 POJO 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28818895/

相关文章:

java - 如何获取 RHINO 中变量的类型?

json - VS402881 : No artifact version is specified corresponding to artifact source 'MyBuild.' Release Management vNext REST API

java - 对于在声明期间初始化的最终变量,Jackson 的行为是否正确?

java - 在 Android 上运行 Appium 测试时出现错误 "An unknown server-side error occurred.."

java - 在不使用读取内容的情况下调用 Scanner 方法是否不好?

java - 将 hashmap 转换为小写

sql - 在 postgresql 中选择查询 >= jsonb 列值

vb.net - 如何将 Handsontable 保存到数据库

java - 无法反序列化,原因未知(MismatchedInputException)

java - Spring MVC @RequestBody 进入接口(interface)而不是类