fastjson 泛型转换问题(详解)

系列文章目录

附属文章一:fastjson TypeReference 泛型类型(详解)



前言

本文讲解使用 fastjson 进行 json 转换泛型 T、泛型集合 R<List>、或者子类中的泛型、或者多层泛型,存在的 json 转换异常报错问题,以及解决方案。


一、代码演示

data 实际对象类型:

@Data
public class SysUser {

    String userId;

    String userName;
}

1. 不存在泛型转换

响应类:

@Data
public class R {

    Integer code;

    String msg;

    SysUser data;
}

测试类:


@Slf4j
public class Test {

    public static void main(String[] args) {
        String jsonStr = "{\"code\":0,\"msg\":\"操作成功\",\"data\":{\"userId\":\"1001\",\"userName\":\"小白\"}}";
        R rSysUser = JSONObject.parseObject(jsonStr, R.class);
        SysUser sysUser = rSysUser.getData();
        log.info("sysUser={}", sysUser.toString());
    }
}

执行上述代码,结果如下:

在这里插入图片描述

通过断点调试可以看到 JSONObject.parseObject(jsonStr, R.class) 转换后的对象中的子对象的实际类型为 SysUser,数据为等值的形式。

2. 存在泛型转换

泛型响应类:

@Data
public class R<T> {

    Integer code;

    String msg;

    T data;
}

泛型测试类:


@Slf4j
public class Test {

    public static void main(String[] args) {
        String jsonStr = "{\"code\":0,\"msg\":\"操作成功\",\"data\":{\"userId\":\"1001\",\"userName\":\"小白\"}}";
        R<SysUser> rSysUser = JSONObject.parseObject(jsonStr, R.class);
        SysUser sysUser = rSysUser.getData();
        log.info("sysUser={}", sysUser.toString());
    }
}

执行上述代码,结果如下:

在这里插入图片描述

通过断点调试可以看到 JSONObject.parseObject(jsonStr, R.class) 转换后的对象中的子泛型对象的实际类型为 JSONObject,数据为 key-value 的形式。

此时往下执行,进行 JSONObject 和 SysUser 对象的直接赋值,就会抛出异常:

在这里插入图片描述

3. 存在泛型集合转换

泛型集合测试类:


@Slf4j
public class Test {

    public static void main(String[] args) {
        String jsonStr = "{\"code\":0,\"msg\":\"操作成功\",\"data\":[{\"userId\":\"1001\",\"userName\":\"小白\"}]}";
        R<List<SysUser>> rSysUser = JSONObject.parseObject(jsonStr, R.class);
        List<SysUser> sysUserList = rSysUser.getData();
        log.info("sysUserList={}", sysUserList.toString());
        SysUser sysUser = sysUserList.get(0);
        log.info("sysUser={}", sysUser.toString());
    }
}

执行上述代码,结果如下:
在这里插入图片描述
通过断点调试可以看到 JSONObject.parseObject(jsonStr, R.class) 转换后的对象中的泛型集合对象的实际类型为 JSONObject,数据为 key-value 的形式。

此时往下执行,进行 JSONObject 和 SysUser 对象的直接赋值,就会抛出异常:
在这里插入图片描述

扩展:

当然,泛型 T、泛型集合 R<List>、或者子类中的泛型、或者多层泛型,都存在同样的问题。本文不再演示。

二、原因分析

因为当 json 转换的对象是泛型时,我们无法获取到实际的类,无法获取到类的变量,也无法获取到类变量的 get、set 方法,所以我们无法将这个 json 数据转换到某一个实际的类对象中存储,所以 com.alibaba.fastjson 会临时转换为 JSONObject 对象,以 key-value 形式存储。

这样就存在一个问题,当我们将该泛型对象赋值转换为实际的类对象时,就会因类型不匹配而抛出异常。

三、解决方案

1. 方案1:重新执行泛型的 json 转换

将泛型转换为 json 字符串后,重新进行类对象转换。

泛型转换:

R<SysUser> rSysUser = JSONObject.parseObject(jsonStr, R.class);
SysUser sysUser = JSONObject.parseObject(JSONObject.toJSONString(rSysUser.getData()), SysUser.class);

泛型集合转换:

R<List<SysUser>> rSysUser = JSONObject.parseObject(jsonStr, R.class);
List<SysUser> sysUserList = JSONObject.parseArray(JSONObject.toJSONString(rSysUser.getData()), SysUser.class);

2. 方案2:使用 TypeReference 指定泛型类型

使用 fastjson 的 TypeReference 来指定泛型类型。

在指定了 json 转换中泛型的实际类型后,就能获取到实际的类,获取到类的变量,获取到类变量的 get、set 方法,从而将泛型的 json 转换成实际的类对象。

本文不过多讲解 TypeReference 类,详细了解请转 《fastjson TypeReference 泛型类型(详解)》https://editor.csdn.net/md/?articleId=139363645

泛型转换:

R<SysUser> rSysUser = JSONObject.parseObject(jsonStr, new TypeReference<R<SysUser>>(){});
SysUser sysUser = rSysUser.getData();

泛型集合转换:

R<List<SysUser>> rSysUser = JSONObject.parseObject(jsonStr, new TypeReference<R<List<SysUser>>>(){});
List<SysUser> sysUserList = rSysUser.getData();
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Java中使用fastjson进行泛型类的反序列化,你可以按照以下步骤进行操作: 首先,确保你已经引入了fastjson的依赖,可以通过Maven等构建工具添加以下依赖项: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.79</version> </dependency> ``` 接下来,假设你有一个泛型类`Result<T>`,如下所示: ```java import com.alibaba.fastjson.JSON; public class Result<T> { private int code; private String message; private T data; public Result(int code, String message, T data) { this.code = code; this.message = message; this.data = data; } public int getCode() { return code; } public String getMessage() { return message; } public T getData() { return data; } public static <T> Result<T> fromJson(String json, Class<T> clazz) { return JSON.parseObject(json, new TypeReference<Result<T>>(clazz) {}.getType()); } } ``` 在上述代码中,`fromJSON`方法使用fastjson的`parseObject`方法将JSON字符串反序列化为`Result<T>`对象。 然后,你可以使用以下代码将JSON字符串反序列化为具体的泛型类对象: ```java import com.alibaba.fastjson.JSON; public class Main { public static void main(String[] args) { String json = "{\"code\":200,\"message\":\"Success\",\"data\":{\"name\":\"John\",\"age\":25}}"; Result<User> result = Result.fromJson(json, User.class); System.out.println("Code: " + result.getCode()); System.out.println("Message: " + result.getMessage()); User user = result.getData(); System.out.println("Name: " + user.getName()); System.out.println("Age: " + user.getAge()); } } ``` 在上述代码中,我们将一个包含`User`对象的JSON字符串反序列化为`Result<User>`对象,并输出其中的字段值。 请注意,为了正确反序列化泛型类,我们需要通过传递`Class<T>`参数给`fromJSON`方法来指定具体的泛型类型。 以上就是使用fastjson进行泛型类反序列化的基本示例。当然,根据实际需求和数据结构的复杂程度,你可能需要进行更多的定制和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Whitemeen太白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值