解决 Jackson反序列化 Unexpected token ... , expected VALUE_STRING: need JSON String that contains type id (for subtype of ...)

首先检查是否是 objectMapper.enableDefaultTyping(); 的受害者。优先考虑删除该配置。

 

使用Jackson把数组的json字符串反序列化为List时候报了个JsonMappingException。

java.lang.UnsupportedOperationException: com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected VALUE_STRING: need JSON String that contains type id (for subtype of java.util.List)
at [Source: [ ......

 

找到问题代码,粗看似乎没什么问题?

List<MyObject> objectList = objectMapper.readValue(jsonString, new TypeReference<List<MyObject>>() {}); //jsonString是个json对象的数组

 

注意到异常信息“need JSON String that contains type id (for subtype of java.util.List)”。想了一会儿,好吧,有答案了。

List<MyObject> objectList = objectMapper.readValue(jsonString, new TypeReference<ArrayList<MyObject>>() {}); //jsonString是个json对象的数组

 

其实,有一种比较老派的反序列化为List的方式...

List<MyObject> objectList = Arrays.asList(objectMapper.readValue(jsonString, MyObject[].class)); //jsonString是个json对象的数组

 

当对一些较复杂的对象进行反序列化时,例如拥有接口类型成员变量的类。举个栗子:

@Data
public class TypeValue {
  private Integer type;
  private List<Integer> value;
}

 

有上面这个类,需要把json字符串反序列化成 Map<String, TypeValue> 这样的对象,怎么做?

可以在TypeValue这个类中使用 @JsonCreator 注解解决。

@Data
public class TypeValue {
  private Integer type;
  private List<Integer> value;

  @JsonCreator    //为Jackson提供构造函数
  public TypeValue(@JsonProperty("type") final Integer type, @JsonProperty("value") final int[] value) {
    this.type= type;
    this.value = Ints.asList(value);
  }
}

Jackson能够把[]数组转换为List。因此可以用以上方法绕过Jackson的限制。

 

 

以上使用了guava和lombok

posted @ 2017-08-04 11:28  傅晓芸  阅读(14696)  评论(0编辑  收藏  举报