【问题标题】:How to use Jackson for parse object follow json type?如何使用 Jackson 解析对象遵循 json 类型?
【发布时间】:2021-09-10 04:07:55
【问题描述】:

我有两个 Json 对象,例如:

  • 对象 1
{
    "value": {
        "data": [
            "John",
            "Justin",
            "Tom"
        ],
        "isGraduated": false
    }
}
  • 对象 2
{
    "value": {
        "data": {
            "info": {
                "background": {
                    "primarySchool" : "A school",
                    "univeristy": "X univeristy"
                },
                "name": "John",
                "gender": "male",
                "dayOfBirth": "1995-04-24"
            }
        },
        "isGraduated": false
    }
}

如何使用 Jackson 将 data 字段反序列化为字符串或类列表(我已经声明)?

编辑

  • 添加类信息声明。
public class Info {
    @JsonProperty("background")
    private BackGround backGround;
    @JsonProperty("name")
    private String name;
    @JsonProperty("gender")
    private String gender;
    @JsonProperty("dayOfBirth")
    private String dayOfBirth;

    public static class BackGround {
        @JsonProperty("primarySchool")
        private String primarySchool;
        @JsonProperty("univeristy")
        private String univeristy;
    }
}

【问题讨论】:

  • 添加你已经声明的类
  • 我已经添加了我已经声明的类。

标签: java-8 jackson deserialization jackson-databind


【解决方案1】:

查看您的 JSON 对象,您无法确定 data 参数中的内容。所以你可以使用JsonNode 作为data 参数的类型。

注意:这是我创建的用于表示 JSON 对象的对象层次结构

@ToString
class Wrapper {
    private Value value;
    
    // getter & setter
}

@ToString
class Value {
    private JsonNode data;
    private Boolean isGraduated;

    // getter & setter
}

@ToString
class Data {
    private Info info;

    // getter & setter
}

@ToString
class Info {
    private Background background;
    private String name;
    private String gender;
    private String dayOfBirth;

    // getter & setter

    @ToString
    static class Background {
        private String primarySchool;
        private String univeristy;

        // getter & setter
    }
}

然后你可以像这样在List<String>Info.calss之间反序列化之前检查节点类型,

JsonNodeType type = value.getValue().getData().getNodeType();

如果 json 对象是类型 1,您将看到 type = JsonNodeType.ARRAY;如果 json 对象是类型 2,您将看到 type = JsonNodeType.OBJECT

检查这个例子,

public class Main {

    public static void main(String[] args) throws IOException {
//        String s = "{\"value\":{\"data\":[\"John\",\"Justin\",\"Tom\"],\"isGraduated\":false}}";
        String s = "{\"value\":{\"data\":{\"info\":{\"background\":{\"primarySchool\":\"A school\",\"univeristy\":\"X univeristy\"},\"name\":\"John\",\"gender\":\"male\",\"dayOfBirth\":\"1995-04-24\"}},\"isGraduated\":false}}";

        ObjectMapper om = new ObjectMapper();
        Wrapper wrapper = om.readValue(s, Wrapper.class);

        JsonNodeType type = wrapper.getValue().getData().getNodeType();

        if (type == JsonNodeType.ARRAY) {
            List<String> data = om.convertValue(wrapper.getValue().getData(), new TypeReference<List<String>>() {});
            System.out.println(data);
        } else if (type == JsonNodeType.OBJECT) {
            Data data = om.convertValue(wrapper.getValue().getData(), Data.class);
            System.out.println(data);
        }
    }
}

【讨论】:

    【解决方案2】:

    不是一般方法,而是针对您的具体情况的方法

    ObjectMapper mapper = new ObjectMapper();
    ObjectNode root = (ObjectNode) mapper.readTree(jsonContent);
    JsonNode data = root.get("value").get("data");
    
    if (data.has("info")) {
        Info result = mapper.convertValue(data.get("info"), Info.class);
        // handle result as Info instance
    } else {
        List<String> result = mapper.convertValue(data, new TypeReference<List<String>>() {});
        // handle result as list of strings
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-22
      • 1970-01-01
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多