[英]Jackson JSON - Extract data from nested array
我目前正在尝试将来自RESTful API的数据反序列化为POJO类。 API的每种方法都返回相同的响应结构,实际结果根据方法的不同而变化。 我希望能够将每个方法的结果映射到其自己的POJO类。
样本JSON响应中有两个具有这种结构,一个返回对象数组,另一个返回一系列属性。
在这种情况下,应将“结果”中的每个JSON对象反序列化为它自己的POJO实例。
{ "success" : true, "message" : "", "result" : [{ "Frequency" : 0.25000 "Range" : 15.6 }, { "Frequency" : 0.12500 "Range" : 25.1 }, { "Frequency" : 0.00750 "Range" : 56.0 } ] }
在这种情况下,“结果”是对象,应映射到单个POJO实例。
{ "success" : true, "message" : "", "result" : { "Bid" : 2.05670368, "Ask" : 3.35579531, "Last" : 3.35579531 } }
这是与先前示例不同的类,因为它是来自其他API方法的响应。 我只想提取结果,任何响应都不需要成功和消息。
由于results
响应是动态的,因此建议您不要在反序列化中包括results
对象。 在执行反序列化的POJO类中包括以下代码。
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
现在Map
名为additionalProperties
将包含你还没有尝试过的父对象捕捉(在这种情况下,将有你的任何其他对象results
对象)。 它根据您的响应存储Object
或Object
list of Objects
您可以使用键值results
访问它。
正如FlemingJp所建议的那样,对于该问题,使用泛型类型似乎是一个非常可行的解决方案,因此我也在此答案中也包括了这一部分。
public class Response<T> {
private boolean success;
private String message;
private T result;
public T getResult() {
return result;
}
public String getMessage () {
return message;
}
public boolean getSuccess() {
return success;
}
}
用法示例
ObjectMapper objectMapper = new ObjectMapper();
// When the result is one object
Response<DistanceStat> res = objectMapper.readValue(data, new TypeReference<Response<DistanceStat>>() {});
// For a collection of objects under result
Response<Collection<DistanceStat>> res = objectMapper.readValue(data, new TypeReference<Response<Collection<DistanceStat>>>() {});
编辑 :
您可以按照以下步骤在杰克逊中反序列化:
ObjectMapper mapper = new ObjectMapper();
String jsonInString //which contains your json data in string
ParentNode parentNode = mapper.readValue(jsonInString, ParentNode.class);
PraentNode
是您的父类。
编辑2 :
Note
:这非常适合您的情况。
这些是您将需要的POJO类,您必须反序列化的父类
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"success",
"message"
})
public class Example {
@JsonProperty("success")
private Boolean success;
@JsonProperty("message")
private String message;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonProperty("success")
public Boolean getSuccess() {
return success;
}
@JsonProperty("success")
public void setSuccess(Boolean success) {
this.success = success;
}
@JsonProperty("message")
public String getMessage() {
return message;
}
@JsonProperty("message")
public void setMessage(String message) {
this.message = message;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
我故意不在此处包含Result
类。 现在,无论您获得什么Result
响应,都将作为additional properties
object
存储在Map
名为additional properties
的object
,该object
可以是list<Result>
或Result
类
现在,您有两个用于Result
对象的结构。 您可以将它们存储在同一POJO中。 因此,让我们为每个结构构造两个不同的POJO类。
Result1.java
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"Frequency",
"Range"
})
public class Result1 {
@JsonProperty("Frequency")
private Double frequency;
@JsonProperty("Range")
private Double range;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonProperty("Frequency")
public Double getFrequency() {
return frequency;
}
@JsonProperty("Frequency")
public void setFrequency(Double frequency) {
this.frequency = frequency;
}
@JsonProperty("Range")
public Double getRange() {
return range;
}
@JsonProperty("Range")
public void setRange(Double range) {
this.range = range;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
Result2.java:
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"Bid",
"Ask",
"Last"
})
public class Result2 {
@JsonProperty("Bid")
private Double bid;
@JsonProperty("Ask")
private Double ask;
@JsonProperty("Last")
private Double last;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonProperty("Bid")
public Double getBid() {
return bid;
}
@JsonProperty("Bid")
public void setBid(Double bid) {
this.bid = bid;
}
@JsonProperty("Ask")
public Double getAsk() {
return ask;
}
@JsonProperty("Ask")
public void setAsk(Double ask) {
this.ask = ask;
}
@JsonProperty("Last")
public Double getLast() {
return last;
}
@JsonProperty("Last")
public void setLast(Double last) {
this.last = last;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
现在,使用以下代码反序列化JSON:
ObjectMapper mapper = new ObjectMapper();
String jsonInString //which contains your json data in string
Example example= mapper.readValue(jsonInString, Example.class);
棘手的部分到了,现在您的地图包含“ Results
响应,但是我们不确定它是对象列表还是对象列表。
现在要获取Results
我们将首先尝试确定它是否是一个集合(因为列表是一个集合),这将有助于我们进行识别。
Object resultObject = example.getAdditionalProperties().getKey("results");
if ( resultObject instanceof Collection<?>){
List<Result1> results=resultObject;
}
else{
Result2 results=resultObject;
}
希望这能解决您的问题!
让我知道您是否需要任何澄清!
我设法解决了我的问题。 我按照Coder的建议使用通用类型创建了ParentNode。 这允许结果中包含任何类型,甚至是集合。
反应等级
public class Response<T> {
private boolean success;
private String message;
private T result;
public T getResult() {
return result;
}
public String getMessage () {
return message;
}
public boolean getSuccess() {
return success;
}
}
ObjectMapper objectMapper = new ObjectMapper(); // When the result is one object Response<DistanceStat> res = objectMapper.readValue(data, new TypeReference<Response<DistanceStat>>() {}); // For a collection of objects under result Response<Collection<DistanceStat>> res = objectMapper.readValue(data, new TypeReference<Response<Collection<DistanceStat>>>() {});
这与我现在正在寻找的一种优雅的解决方案非常接近,现在将有助于避免第二个用法示例中的三重类型定义。
注意:我接受Coder的回答,因为它会导致此解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.