Gson(泛型)如何“动态”反序列化类属性ClassCastException

发布于 2022-09-06 15:29:31 字数 1664 浏览 20 评论 0

这个问题实在是不知道怎么取标题

异常如下:

Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to XXX

我举例说明:

已知有一个User类,包含了一些简单的属性

public class User{
    private String userName;
    private String gender;
    
    //get set方法省略
}

然后我有一个专门用于数据传输的json包装类

public class JsonMessage<T>{
    private Integer code;
    private String msg;
    private T data;
    
    //get set方法省略
}

然后我有一个主方法

public static void main(String[] args){
    //有一个待序列化的json字符串
    String jsonStr = "{'code':123,'msg':'test','data':{'userName':'baofeidyz','gender':'male'}}";
    //然后使用Gson序列化
    Gson gson = new Gson();
    JsonMessage<User> message = gson.fromJson(jsonStr,JsonMessage.class);
    //然后在这里我尝试获取data中的数据,就报
    //Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to User
}

可是当我不使用泛型的时候就是OK的:

我这里有一个新的json包装类

public class JsonMessage2{
    private Integer code;
    private String msg;
    private User data;
    
    //get set方法省略
}

然后我又新建了一个新的main方法:

public static void main(String[] args){
    //还是那个待序列化的json字符串
    String jsonStr = "{'code':123,'msg':'test','data':{'userName':'baofeidyz','gender':'male'}}";
    //然后使用Gson序列化
    Gson gson = new Gson();
    //这里换成了新的包装类
    JsonMessage2 message = gson.fromJson(jsonStr,JsonMessage2.class);
    //然后就成功获取到了数据
}

代码是我在segmentfault网页现敲的,但是问题是和我实际问题一样。
个人觉得主要是我对泛型和Gson的序列化方式理解有问题,所以想请教一下各位,感谢!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

日裸衫吸 2022-09-13 15:29:31

自问自答了。

我解决了。

在Gson反序列化的过程中,如果你需要传泛型需要这样操作:

JsonMessage<User> message = gson.fromJson(jsonStr,new TypeToken<JsonMessage<User>>(){}.getType());

其实我以前就遇到过这个问题,只是这次发生的场景变了,这个问题实际上是在写SpringBoot的Controller的时候遇到的

最后的解决方案是修改传入参数的key,需要和包装类的属性名相同才可以,不过建议彻底去除jackson改成集成gson会比较好

然后就可以非常简单的使用@RequestBody来拿到数据对象

甜是你 2022-09-13 15:29:31

我试了一下,GSON 2.7 并没有出现这个异常。

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.7</version>
</dependency>
两个我 2022-09-13 15:29:31

不同框架/库有个字的拿泛型参数的类,不过原理都一样

  • Gson 是 TypeToken
  • Jackson 是 TypeReference
  • Spring 也有自己的 ParameterizedTypeReference

不过题主要在 @RequestBody 里用就非常奇怪了…

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文