java Jackson 无法反序列化空数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25166301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hymanson Can not deserialize empty array
提问by Reusable
Im reading the Facebook Insights and trying to get Hymanson to map the JSON to Object. If all the data comes in without empty, i have it working. But Im having a problem trying to deserialize empty array of key value. Even after trying this post: How to prevent null values inside a Map and null fields inside a bean from getting serialized through Hymansonit did not resolve the problem :(
我正在阅读 Facebook Insights 并试图让 Hymanson 将 JSON 映射到对象。如果所有数据都没有为空,我就可以正常工作。但是我在尝试反序列化空的键值数组时遇到了问题。即使在尝试这篇文章之后:如何防止 Map 中的空值和 bean 中的空字段通过 Hymanson 序列化它也没有解决问题:(
This is the JSON :
这是 JSON :
{"data":[{"id":"492640667465465\/insights\/page_fans_country\/lifetime","name":"page_fans_country","period":"lifetime","values":[{"value":{"MY":26315,"ID":311,"SG":77,"NP":63,"MM":56,"PH":51,"GB":44,"US":44,"KR":36,"TH":36,"IN":34,"BD":24,"PK":22,"BN":22,"AU":15,"TW":14,"VN":12,"KH":11,"YE":11,"CA":10,"JP":10,"EG":8,"ZA":7,"SA":6,"ES":6,"HK":6,"FR":6,"IT":5,"IL":5,"IR":5,"NG":5,"LK":5,"BR":5,"IQ":4,"AF":4,"AE":4,"GT":4,"RO":4,"LR":4,"RU":4,"PS":4,"DE":4,"CN":4,"LY":3,"JO":3},"end_time":"2014-08-02T07:00:00+0000"},{"value":{"MY":26326,"ID":315,"SG":77,"NP":63,"MM":56,"PH":54,"GB":44,"US":43,"TH":38,"KR":36,"IN":33,"BD":23,"BN":22,"PK":21,"AU":16,"TW":14,"VN":12,"KH":11,"YE":11,"CA":10,"JP":10,"EG":8,"ZA":7,"SA":7,"ES":6,"HK":6,"FR":6,"IT":5,"IL":5,"IR":5,"NG":5,"LK":5,"BR":5,"IQ":4,"RU":4,"CN":4,"GT":4,"RO":4,"LR":4,"AF":4,"PS":4,"DE":4,"AE":4,"LY":3,"CH":3},"end_time":"2014-08-03T07:00:00+0000"},{"value":{"MY":26338,"ID":312,"SG":79,"NP":63,"MM":55,"PH":52,"US":45,"GB":44,"TH":39,"KR":34,"IN":32,"BD":24,"BN":22,"PK":21,"AU":16,"TW":14,"KH":12,"VN":12,"CA":11,"YE":11,"JP":10,"EG":8,"ZA":7,"SA":7,"ES":6,"HK":6,"FR":6,"IT":5,"CN":5,"IR":5,"NG":5,"LK":5,"BR":5,"IL":5,"IQ":4,"AF":4,"AE":4,"GT":4,"RO":4,"LR":4,"RU":4,"PS":4,"DE":4,"NZ":3,"TR":3},"end_time":"2014-08-04T07:00:00+0000"}],"title":"Lifetime Likes by Country","description":"Lifetime: Aggregated Facebook location data, sorted by country, about the people who like your Page. (Unique Users)"},{"id":"492640667465465\/insights\/page_storytellers_by_country\/day","name":"page_storytellers_by_country","period":"day","values":[{"value":[],"end_time":"2014-08-02T07:00:00+0000"},{"value":[],"end_time":"2014-08-03T07:00:00+0000"},{"value":[],"end_time":"2014-08-04T07:00:00+0000"}],"title":"Daily Country: People Talking About This","description":"Daily: The number of People Talking About the Page by user country (Unique Users)"},{"id":"492640667465465\/insights\/page_storytellers_by_country\/week","name":"page_storytellers_by_country","period":"week","values":[{"value":{"MY":136,"IN":3,"ID":2,"BD":1,"US":1,"TN":1,"AU":1},"end_time":"2014-08-02T07:00:00+0000"},{"value":{"MY":131,"IN":3,"US":1,"TN":1,"AU":1,"ID":1},"end_time":"2014-08-03T07:00:00+0000"},{"value":{"MY":118,"IN":2,"KH":1,"TR":1,"US":1,"TN":1,"AR":1,"AU":1},"end_time":"2014-08-04T07:00:00+0000"}],"title":"Weekly Country: People Talking About This","description":"Weekly: The number of People Talking About the Page by user country (Unique Users)"},{"id":"492640667465465\/insights\/page_storytellers_by_country\/days_28","name":"page_storytellers_by_country","period":"days_28","values":[{"value":{"MY":492,"IN":5,"ID":3,"AU":2,"SG":2,"ZA":2,"US":2,"GB":2,"RO":1,"PH":1,"NP":1,"BD":1,"JO":1,"PS":1,"TN":1,"IR":1,"CA":1,"CN":1,"KR":1},"end_time":"2014-08-02T07:00:00+0000"},{"value":{"MY":499,"IN":5,"ID":3,"GB":2,"SG":2,"ZA":2,"US":2,"RO":1,"PH":1,"NP":1,"BD":1,"AU":1,"CN":1,"KR":1,"TN":1,"IR":1,"CA":1,"JO":1},"end_time":"2014-08-03T07:00:00+0000"},{"value":{"MY":501,"IN":4,"ID":3,"SG":2,"ZA":2,"US":2,"GB":2,"AU":1,"RO":1,"PH":1,"NP":1,"JO":1,"AR":1,"KR":1,"BD":1,"TR":1,"IR":1,"CA":1,"CN":1,"KH":1,"TN":1},"end_time":"2014-08-04T07:00:00+0000"}],"title":"28 Days Country: People Talking About This","description":"28 Days: The number of People Talking About the Page by user country (Unique Users)"}],"paging":{"previous":"https:\/\/graph.facebook.com\/v2.0\/492640667465465\/insights?since=1406649169&until=1406908369","next":"https:\/\/graph.facebook.com\/v2.0\/492640667465465\/insights?since=1407167569&until=1407426769"}}
My current code does not like this at all --> "value":[]
我当前的代码根本不喜欢这个 --> "value":[]
And the follwing is my Object:
以下是我的对象:
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.fasterxml.Hymanson.annotation.JsonInclude;
import com.fasterxml.Hymanson.annotation.JsonInclude.Include;
public class Insights {
private Data[] data;
private Paging paging;
public Data[] getData() {
return data;
}
public void setData(Data[] data) {
this.data = data;
}
public Paging getPaging() {
return paging;
}
public void setPaging(Paging paging) {
this.paging = paging;
}
/**
* inner class for Data
* @author pohsoon.yap
*
*/
public static class Data {
private String id;
private String name;
private String period;
private Values[] values;
private String title;
private String description;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPeriod() {
return period;
}
public void setPeriod(String period) {
this.period = period;
}
public Values[] getValues() {
return values;
}
public void setValues(Values[] values) {
this.values = values;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/**
* inner class for Values
* @author pohsoon.yap
*
*/
public static class Values {
// if "value":[] then this will break
private Map<String, Integer> Value;
private String end_time;
public Map<String, Integer> getValue() {
return Value;
}
public void setValue(Map<String, Integer> value) {
Value = value;
}
public String getEnd_time() {
return end_time;
}
public void setEnd_time(String end_time) {
this.end_time = end_time;
}
}
}
public static class Paging {
private String previous;
private String next;
public String getPrevious() {
return previous;
}
public void setPrevious(String previous) {
this.previous = previous;
}
public String getNext() {
return next;
}
public void setNext(String next) {
this.next = next;
}
}
}
My code snippet as follows:
我的代码片段如下:
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
List<Insights> insightList = new ArrayList();
String insightStr = "";
try {
for (Operation operation : mq.getOperationList()){
String apiEndPoint = this.facebookGraphApiUrl + operation.getApi();
apiEndPoint = apiEndPoint.replace("{pageid}", mq.getFacebookPage().getPageId());
uri = new URI(apiEndPoint);
insightStr = facebook.getApi().restOperations().getForObject(uri, String.class);
Insights insights = mapper.readValue(insightStr, Insights.class);
The full stack trace:
完整的堆栈跟踪:
com.fasterxml.Hymanson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token at [Source: java.io.StringReader@625a80df; line: 1, column: 1603] (through reference chain: com.social.facebook.model.Insights["data"]->com.social.facebook.model.Data["values"]->com.social.facebook.model.Values["value"]) at com.fasterxml.Hymanson.databind.JsonMappingException.from(JsonMappingException.java:164) at com.fasterxml.Hymanson.databind.DeserializationContext.mappingException(DeserializationContext.java:599) at com.fasterxml.Hymanson.databind.DeserializationContext.mappingException(DeserializationContext.java:593) at com.fasterxml.Hymanson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:306) at com.fasterxml.Hymanson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:26) at com.fasterxml.Hymanson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375) at com.fasterxml.Hymanson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98) at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:308) at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) at com.fasterxml.Hymanson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:147) at com.fasterxml.Hymanson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:18) at com.fasterxml.Hymanson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375) at com.fasterxml.Hymanson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98) at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:308) at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) at com.fasterxml.Hymanson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:147) at com.fasterxml.Hymanson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:18) at com.fasterxml.Hymanson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375) at com.fasterxml.Hymanson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98) at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:308) at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) at com.fasterxml.Hymanson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2796) at com.fasterxml.Hymanson.databind.ObjectMapper.readValue(ObjectMapper.java:1942)
com.fasterxml.Hymanson.databind.JsonMappingException:无法从 [来源:java.io.StringReader@625a80df; 的 START_ARRAY 令牌中反序列化 java.util.LinkedHashMap 的实例;行:1,列:1603](通过参考链:com.social.facebook.model.Insights["data"]->com.social.facebook.model.Data["values"]->com.social.facebook .model.Values["value"]) 在 com.fasterxml.Hymanson.databind.JsonMappingException.from(JsonMappingException.java:164) 在 com.fasterxml.Hymanson.databind.DeserializationContext.mappingException(DeserializationContext.java:599) 在 com .fasterxml.Hymanson.databind.DeserializationContext.mappingException(DeserializationContext.java:593) 在 com.fasterxml.Hymanson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:306) 在 com.fasterxml.Hymanson。
采纳答案by Alexey Gavrilov
The value
field in your model is declared as Map
while the corresponding JSON property can be either an empty array or a key-value map. Hymanson cannot assign an empty array to a map field.
value
模型中的字段声明为,Map
而相应的 JSON 属性可以是空数组或键值映射。Hymanson 不能将空数组分配给地图字段。
Assuming that you wish to solve the problem on the client side, you can modify the setValue
method to accept a generic Object
and then verify whether it is a map or an array (actually List
since Hymanson deserialize arrays as Java collections). Here is an example:
假设您希望在客户端解决问题,您可以修改setValue
方法以接受泛型Object
,然后验证它是映射还是数组(实际上是List
因为 Hymanson 将数组反序列化为 Java 集合)。下面是一个例子:
public class HymansonArrayAsMap {
public static class Bean {
private Map<String, Object> value;
public void setValue(Object value) {
if (value instanceof Map) {
this.value = (Map<String, Object>) value;
} else if (value instanceof List && ((List) value).size() == 0){
this.value = Collections.EMPTY_MAP;
} else {
throw new IllegalArgumentException("Invalid value: " + value);
}
}
@Override
public String toString() {
return "Bean{" +
"value=" + value +
'}';
}
}
public static void main(String[] args) throws IOException {
final String json1 = "{\"value\":{}}";
final String json2 = "{\"value\":[]}";
final String json3 = "{\"value\":{\"a\":\"b\"}}";
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(json1, Bean.class));
System.out.println(mapper.readValue(json2, Bean.class));
System.out.println(mapper.readValue(json3, Bean.class));
}
}
Output:
输出:
Bean{value={}}
Bean{value={}}
Bean{value={a=b}}
回答by StaxMan
As explained by others, you are trying to map JSON Array into Java Map, something that is not allowed by default.
正如其他人所解释的,您正在尝试将 JSON 数组映射到 Java Map,这是默认情况下不允许的。
But it may be possible to allow empty JSON Array to map to java.util.Map
. by enabling DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT
:
但是有可能允许空的 JSON 数组映射到java.util.Map
. 通过启用DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT
:
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);
this at least works in case of a POJO type; I do not recall if this works for other Java types that usually take JSON Object.
这至少适用于 POJO 类型;我不记得这是否适用于通常采用 JSON 对象的其他 Java 类型。