Java 来自SpringRestClient和Jackson的嵌套JSON对象

Java 来自SpringRestClient和Jackson的嵌套JSON对象,java,json,spring,jackson-databind,Java,Json,Spring,Jackson Databind,我有一个rest客户端,它将从端点获取JSON。我只想得到数据中的内容[] { "responseStatus": "SUCCESS", "responseDetails": { "limit": 1000, "offset": 0, "size": 2, "total": 2 }, "data": [ { "id": "00P000000001M01",

我有一个rest客户端,它将从端点获取JSON。我只想得到数据中的内容[]

{
    "responseStatus": "SUCCESS",
    "responseDetails": {
        "limit": 1000,
        "offset": 0,
        "size": 2,
        "total": 2
    },
    "data": [
        {
            "id": "00P000000001M01",
            "name__v": "Foo",
            "status__v": [
                "active__v"
            ],
            "abbreviation__c": "F170053",
            "internal_name__c": "Foo",
            "therapeutic_area__c": [
                "neurology__c"
            ],
            "external_id__v": "84",
            "generic_name__c": "Foo",
            "scientific_name__c": null
        },
        {
            "id": "00P000000001N01",
            "name__v": "Bar",
            "status__v": [
                "active__v"
            ],
            "abbreviation__c": "B333334",
            "internal_name__c": "Bar",
            "therapeutic_area__c": [
                "bone_muscle_joint__c"
            ],
            "external_id__v": "101",
            "generic_name__c": "Bar",
            "scientific_name__c": null
        }
    ]
}
因为我将进行其他调用,这些调用将返回数据[]中的不同字段,所以我想将每个类型映射到POJO,所以我使用了@JSONProperty

@JsonIgnoreProperties(ignoreUnknown = true)
public class Product extends VBase{
    private String fNumber;
    private String genericName;
    private String scientificName;
    private String therapeuticArea;


    public String getFNumber() {
        return fNumber;
    }

    @JsonProperty("abbreviation__c")
    private void unpackFNumber(Map<String,Object> abbreviation__c){
        fNumber = ((Map<String,Object>)abbreviation__c.get("data")).get("abbreviation__c").toString();
    }
    public void setLyNumber(String fNumber) {
        this.fNumber = fNumber;
    }

    public String getGenericName() {
        return genericName;
    }


    @JsonProperty("generic_name__c")
    private void unpackGenericName(Map<String,Object> generic_name__c){
        genericName = ((Map<String,Object>)generic_name__c.get("data")).get("generic_name__c").toString();
    }
    public String getScientificName() {
        return scientificName;
    }

    @JsonProperty("scientific_name__c")
    private void unpackScientificName(Map<String,Object>sName){
        scientificName = ((Map<String,Object>)sName.get("data")).get("scientific_name__c").toString();
    }

    public String getTherapeuticArea() {
        return therapeuticArea;
    }

    @JsonProperty("therapeutic_area__c")
    private void unpackTheraputicArea(Map<String,Object>tArea){
        therapeuticArea=((Map<String,Object>)tArea.get("data")).get("therapeutic_area__c").toString();
    }
}

按照下面的代码声明POJO类,然后可以从POJO获取数据属性

@Data
public class Example {
    private String responseStatus;
    private ResponseDetails responseDetails;
    private List<Data> data;

    @lombok.Data
    public static class ResponseDetails {
        private int limit;
        private int offset;
        private int size;
        private int total;
    }

    @lombok.Data
    public static class Data {
        private String id;
        private String name__v;
        private String abbreviation__c;
        private String internal_name__c;
        private String external_id__v;
        private String generic_name__c;
        private Object scientific_name__c;
        private List<String> status__v;
        private List<String> therapeutic_area__c;
    }

    @lombok.Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Product {
        @JsonProperty("name__v")
        private String fNumber;
        @JsonProperty("generic_name__c")
        private String genericName;
        @JsonProperty("scientific_name__c")
        private String scientificName;
        @JsonProperty("therapeutic_area__c")
        private List<String> therapeuticArea;
    }

    public static void main(String[] args) {
        String jsonResult = "{\"responseStatus\":\"SUCCESS\",\"responseDetails\":{\"limit\":1000,\"offset\":0,\"size\":2,\"total\":2},\"data\":[{\"id\":\"00P000000001M01\",\"name__v\":\"Foo\",\"status__v\":[\"active__v\"],\"abbreviation__c\":\"F170053\",\"internal_name__c\":\"Foo\",\"therapeutic_area__c\":[\"neurology__c\"],\"external_id__v\":\"84\",\"generic_name__c\":\"Foo\",\"scientific_name__c\":null},{\"id\":\"00P000000001N01\",\"name__v\":\"Bar\",\"status__v\":[\"active__v\"],\"abbreviation__c\":\"B333334\",\"internal_name__c\":\"Bar\",\"therapeutic_area__c\":[\"bone_muscle_joint__c\"],\"external_id__v\":\"101\",\"generic_name__c\":\"Bar\",\"scientific_name__c\":null}]}";
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Example example = objectMapper.readValue(jsonResult, new TypeReference<Example>() {
            });
            //you can get data[] via example.getData()
            System.out.println(objectMapper.writeValueAsString(example.getData()));

            List<Product> products = objectMapper.readValue(objectMapper.writeValueAsString(example.getData()), new TypeReference<List<Product>>() {
            });
            //you can also parse data[] as List<Product>
            System.out.println(JSONObject.toJSONString(products));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
@数据
公开课范例{
私有字符串响应状态;
私人响应详细信息响应详细信息;
私人名单数据;
@龙目数据
公共静态类响应详细信息{
私有整数限制;
私有整数偏移;
私有整数大小;
私人整数合计;
}
@龙目数据
公共静态类数据{
私有字符串id;
私有字符串名称\uuuv;
私有字符串缩写\uuuc;
私有字符串内部名称;
私有字符串外部\u id\u v;
私有字符串通用名称;
私有对象科学名称;
私人名单状态;
私人名单治疗区;
}
@龙目数据
@JsonIgnoreProperties(ignoreUnknown=true)
公共静态类产品{
@JsonProperty(“名称”)
私有字符串fNumber;
@JsonProperty(“通用名称”)
私有字符串genericName;
@JsonProperty(“科学名称”)
私有字符串科学名称;
@JsonProperty(“治疗区c”)
私人区域;
}
公共静态void main(字符串[]args){
目前,1000,“偏移量”:0 0,“尺寸”:0,,,,,,,,,,,,,,,,,,,,,,,,,,,,“尺寸”:2,,,,“总尺寸”:2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,UuC\“],“外部id”:“84\”,““科学名称”和“科学名称”uuuuuuuu c\\:零:,,,,{“id”id\:“00P000000001N01\”,,“名称”uuuuuuuU U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U c\\\\\\ \”:::,,,“通用通用名”U U U U U U U U U U U U U U U U U U U U U U U U U名称”U U U U U U U U U U U U U U U U U c\\\\\\\\\\\\\\\\\\\\\\\\\\ \ \ \ \ \ \“U c\\“c\\ \“c\\ \”,,,,,,,“U U U U U U U U U U U U U U U U U U U U U U U U U U U U U通用名称“:”Bar“,”科学名称“:”null}]}”;
ObjectMapper ObjectMapper=新的ObjectMapper();
试一试{
示例=objectMapper.readValue(jsonResult,new TypeReference(){
});
//您可以通过example.getData()获取数据[]
System.out.println(objectMapper.writeValueAsString(example.getData());
List products=objectMapper.readValue(objectMapper.writeValueAsString(example.getData()),new TypeReference(){
});
//您还可以将数据[]解析为列表
System.out.println(JSONObject.toJSONString(products));
}捕获(IOE异常){
e、 printStackTrace();
}
}
}

如果我还有30个表示数据中可能存在的内容的POJO,这是最好的方法吗[]?我认识到我可能需要一个响应的详细信息,因为我打任何电话都不会改变这一部分。数据[]中的内容已更改。由于不匹配PutException而不起作用。我以前在尝试您的答案并添加错误[]以解决问题时看到了这一点。我必须将error类从一个内部类移动到它自己的类。无法对数据执行此操作(上面给出了原因)。显然,您可以在堆栈中看到错误信息,即
不匹配InputException:无法反序列化com.lilly.models.Product[]的实例,因为它超出了START\u对象标记。
这意味着您的json字符串无法与pojo属性匹配。也许您可以将
产品[]
更改为
列表
,并将
字符串
更改为
列表区域
。顺便说一句,它在我的答案代码中起作用。我已经将POJO更改为您发布的lombok数据注释。它将加载数据类,但不会加载产品类。部分问题可能是我的字符串来自REST调用,我使用的是SpringBoot,因此是内置的Jackson数据绑定。我可以使这项工作在一个全面的时尚。
Exception in thread "main" org.springframework.web.client.RestClientException: Error while extracting response for type [class [Lcom.lilly.models.Product;] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `com.lilly.models.Product[]` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.lilly.models.Product[]` out of START_OBJECT token
 at [Source: (PushbackInputStream); line: 1, column: 1]
@Data
public class Example {
    private String responseStatus;
    private ResponseDetails responseDetails;
    private List<Data> data;

    @lombok.Data
    public static class ResponseDetails {
        private int limit;
        private int offset;
        private int size;
        private int total;
    }

    @lombok.Data
    public static class Data {
        private String id;
        private String name__v;
        private String abbreviation__c;
        private String internal_name__c;
        private String external_id__v;
        private String generic_name__c;
        private Object scientific_name__c;
        private List<String> status__v;
        private List<String> therapeutic_area__c;
    }

    @lombok.Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Product {
        @JsonProperty("name__v")
        private String fNumber;
        @JsonProperty("generic_name__c")
        private String genericName;
        @JsonProperty("scientific_name__c")
        private String scientificName;
        @JsonProperty("therapeutic_area__c")
        private List<String> therapeuticArea;
    }

    public static void main(String[] args) {
        String jsonResult = "{\"responseStatus\":\"SUCCESS\",\"responseDetails\":{\"limit\":1000,\"offset\":0,\"size\":2,\"total\":2},\"data\":[{\"id\":\"00P000000001M01\",\"name__v\":\"Foo\",\"status__v\":[\"active__v\"],\"abbreviation__c\":\"F170053\",\"internal_name__c\":\"Foo\",\"therapeutic_area__c\":[\"neurology__c\"],\"external_id__v\":\"84\",\"generic_name__c\":\"Foo\",\"scientific_name__c\":null},{\"id\":\"00P000000001N01\",\"name__v\":\"Bar\",\"status__v\":[\"active__v\"],\"abbreviation__c\":\"B333334\",\"internal_name__c\":\"Bar\",\"therapeutic_area__c\":[\"bone_muscle_joint__c\"],\"external_id__v\":\"101\",\"generic_name__c\":\"Bar\",\"scientific_name__c\":null}]}";
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Example example = objectMapper.readValue(jsonResult, new TypeReference<Example>() {
            });
            //you can get data[] via example.getData()
            System.out.println(objectMapper.writeValueAsString(example.getData()));

            List<Product> products = objectMapper.readValue(objectMapper.writeValueAsString(example.getData()), new TypeReference<List<Product>>() {
            });
            //you can also parse data[] as List<Product>
            System.out.println(JSONObject.toJSONString(products));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}