[alibaba/fastjson]泛型解析时偶尔出现com.alibaba.fastjson.JSONObject cannot be cast to

2025-11-13 644 views
9
使用fastjson转泛型时遇到的几个问题和疑问

现象:每次上线重启机器之后,定时任务处理某个业务总会出现异常java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to com.jiedaibao.umg.consumer.third.p2proute.rsp.PrtUnBindRsp

  • 分析:代码都是同一套,对出现问题机器重启之后,定时任务跑到其他机子上去后又正常了
  • 原因:ParserConfig.Java,getDeserializer缓存导致

疑问1: 为什么String转成PtpRouteBaseRsp < PrtUnBindRsp > 时,ParseConfig要取Class<?>,而这个class则是rawType,却不直接取type,PtpRouteBaseRsp < PrtUnBindRsp > 。如下ParseConfig类中getDeserializer(Class<?> clazz, Type type) 方法

`

     if (type instanceof ParameterizedType) {

        Type rawType = ((ParameterizedType) type).getRawType();
        if (rawType instanceof Class<?>) {
            return getDeserializer((Class<?>) rawType, type);
        } else {
            return getDeserializer(rawType);
        }
    }

    if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
        derializer = derializers.get(clazz);
    }`

疑问2: ParseConfig中的derializers还有作用域吗,我自己试了几个案例如下,结果: (1)当在main函数执行带泛型,不带泛型,带泛型,分别是true,true,false,说明第三个使用了第二个不带泛型的缓存。 (2)当把带泛型和不带泛型分别放在bbb和aaa方法里,则执行之后结果都是true 麻烦解释下

`

public static void main(String[] args) {

    //true
    String a ="{\"error\":{\"returnCode\":\"0\",\"returnMessage\":\"操作成功\",\"returnUserMessage\":\"操作成功\"},\"data\":{\"errCode\":\"\"},\"logid\":\"6469558a598c04a139a5111908890102\"}";
    PtpRouteBaseRsp<PrtUnBindRsp> itemResult2= JSON.parseObject(a,new TypeReference<PtpRouteBaseRsp<PrtUnBindRsp>>(){});
    System.out.println(itemResult2.getData() instanceof PrtUnBindRsp);

    //true
    String b ="{\"error\":{\"returnCode\":\"0\",\"returnMessage\":\"操作成功\",\"returnUserMessage\":\"操作成功\"},\"data\":{},\"logid\":\"6469558f598c14c4b345129804913202\"}";
    PtpRouteBaseRsp resultFromClass2 = JSON.parseObject(b, new TypeReference<PtpRouteBaseRsp>() {});
    System.out.println(resultFromClass2.getData() instanceof JSON);

    //false
    String c ="{\"error\":{\"returnCode\":\"0\",\"returnMessage\":\"操作成功\",\"returnUserMessage\":\"操作成功\"},\"data\":{\"errCode\":\"\"},\"logid\":\"6469558a598c04a139a5111908890102\"}";
    PtpRouteBaseRsp<PrtUnBindRsp> itemResult3= JSON.parseObject(c,new TypeReference<PtpRouteBaseRsp<PrtUnBindRsp>>(){});
    System.out.println(itemResult3.getData() instanceof PrtUnBindRsp);

 /*   //true
    bbb();
    //true
    aaa();
    //true
    bbb();*/

}
private static void aaa(){
    String b ="{\"error\":{\"returnCode\":\"0\",\"returnMessage\":\"操作成功\",\"returnUserMessage\":\"操作成功\"},\"data\":{},\"logid\":\"6469558f598c14c4b345129804913202\"}";
    PtpRouteBaseRsp resultFromClass2 = JSON.parseObject(b, new TypeReference<PtpRouteBaseRsp>() {});
    System.out.println(resultFromClass2.getData() instanceof JSON);
}
private static void bbb(){
    String a ="{\"error\":{\"returnCode\":\"0\",\"returnMessage\":\"操作成功\",\"returnUserMessage\":\"操作成功\"},\"data\":{\"errCode\":\"\"},\"logid\":\"6469558a598c04a139a5111908890102\"}";
    PtpRouteBaseRsp<PrtUnBindRsp> itemResult2= JSON.parseObject(a,new TypeReference<PtpRouteBaseRsp<PrtUnBindRsp>>(){});
    System.out.println(itemResult2.getData() instanceof PrtUnBindRsp);
}

`

回答

4

更新到最新版本后,没有这个问题。我之前用的是1.1.39版本,能否说明之前版本是哪里有问题

1

PtpRouteBaseRsp的定义发出来

4

这个问题修复过的,是泛型字段和非泛型混合使用导致的

7

是的,大致原因我也知道,混合使用导致泛型字段获取的是非泛型的缓存。@kimmking我就不贴了类定义了哈。 主要想问问真正原因,有时通过定义3个方法分别调用泛型和非泛型又不会有问题,想知道关键点在哪里

9

 你如何解决这个问题?

1

原来泛型缓存有bug,已经修复过,新版本没问题就用新版本吧