Java 来自SpringRestClient和Jackson的嵌套JSON对象
我有一个rest客户端,它将从端点获取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",
{
"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();
}
}
}