首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >杰克逊并没有反序列化一个已经序列化的通用列表。

杰克逊并没有反序列化一个已经序列化的通用列表。
EN

Stack Overflow用户
提问于 2011-05-19 16:46:47
回答 1查看 25.5K关注 0票数 16

当使用Apache泽西与Jackson一起进行JSON序列化时(在服务器和客户端),我在反序列化泛型列表时遇到了一个问题。

我正在生成的JSON如下所示,"data“中的所有3个类都实现了"CheckStatusDetail":

代码语言:javascript
复制
{
  "errorCode" : 0,
  "errorMessage" : null,
  "type" : "array",
  "data" : [ {
    "@class" : "com.rrr.base.status.module.dto.DiscoveryAgentCheckStatusDetail",
    "serverInfo" : {
      "@class" : "com.rrr.base.util.discovery.config.xml.XMLServerInfo",
      "name" : "java",
      "location" : "THEO",
      "description" : "sddgs",
      "group" : "java",
      "aliases" : [ "mercury" ]
    }
  }, {
    "@class" : "com.rrr.base.status.module.dto.MongoDBCheckStatusDetail",
    "addresses" : [ "localhost:27017" ],
    "version" : "2.5",
    "connected" : true
  }, {
    "@class" : "com.rrr.base.status.module.dto.NetworkCheckStatusDetail",
    "splitBrain" : false
  } ],
  "count" : 3,
  "status" : 0
}

生成此JSON的对象如下所示,我在客户端使用相同的类:

代码语言:javascript
复制
public class NSResponse<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    public static final int STATUS_OK       = 0;
    public static final int STATUS_ERROR    = -1;

    public static final String TYPE_OBJECT  = "object";
    public static final String TYPE_ARRAY   = "array";

    private int status;
    private int errorCode;
    private String errorMessage;
    private String type;

    private List<T> data;

    private int count;

    public NSResponse() {   }

    public NSResponse(int errorCode, String errorMessage) {
        this.status = STATUS_ERROR;
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }

    public NSResponse(T data) {
        this.status = STATUS_OK;
        this.type = TYPE_OBJECT;
        this.data = new ArrayList<T>();
        this.data.add(data);
        this.count = this.data.size();
    }

    public NSResponse(List<T> data) {
        this.status = STATUS_OK;
        this.type = TYPE_ARRAY;
        this.data = data;
        this.count = (data == null) ? 0 : data.size();
    }

    /* Getters and setters omitted */
}

自从我将这个注释添加到我的CheckStatusDetail接口后,@class信息就被应用了:

代码语言:javascript
复制
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
public interface CheckStatusDetail extends Serializable {}

当试图在客户端使用JSON时,我得到以下错误:

代码语言:javascript
复制
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.rrr.base.status.module.dto.CheckStatusDetail

这个错误发生在我第一次尝试访问反序列化"data“字段时。如果我调试客户端,Jackson似乎返回了一个List,这解释了错误,因为我期待的是一个List

我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-05-20 23:17:23

您需要显示更多代码,特别是关于如何调用反序列化的代码,但从错误中我猜您没有传递T的参数化。如果缺少参数化,则只能假定T是对象类型,而标称类型的对象绑定到“原生”Java类型,对于JSON对象来说,这种类型是Map (具体来说,是保留顺序的LinkedHashMap )。

因此,您可能只需要在反序列化时指定对象的泛型类型(对于序列化,不需要它,因为运行时类型是可用的);要么使用TypeReference (不是普通类,因为它没有泛型类型信息),要么构造启用泛型的JavaType。例如:

代码语言:javascript
复制
NSResponse<CheckStatusDetail> resp = mapper.readValue(json, new TypeReference<NSResponse<CheckStatusDetail>>() { });

代码语言:javascript
复制
NSResponse<CheckStatusDetail> resp = mapper.readValue(json, TypeFactory.genericType(NSResponse.class, CheckStatusDetails.class));

这两种方法都是可行的;如果type是动态可用的,则后者是必需的。

票数 29
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6062011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档