专栏首页10km的专栏fastjson:对于Exception中复杂类型(enum,...以及自定义类型)成员的处理

fastjson:对于Exception中复杂类型(enum,...以及自定义类型)成员的处理

如果一个Exception类中有枚举类型或其他复杂类型(比如java.util.Date,或自定义类型)的成员,fastjson反序列化会抛出异常。

    // ServiceSecurityException 类型中 type 成员是个枚举类型SecurityExceptionType
    ServiceSecurityException exp = new ServiceSecurityException("hello").setType(SecurityExceptionType.INVALID_PERSON_ID).setDeviceID(10);
    // 序列化可以正常输出
    System.out.println(JSON.toJSONString(exp));
    // 反序列化就会抛出异常
    JSON.parseObject(JSON.toJSONString(exp), ServiceSecurityException.class);

抛出的异常如下:

com.alibaba.fastjson.JSONException: set property error, type at com.alibaba.fastjson.parser.deserializer.FieldDeserializer.setValue(FieldDeserializer.java:136) at com.alibaba.fastjson.parser.deserializer.ThrowableDeserializer.deserialze(ThrowableDeserializer.java:132) at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:626) at com.alibaba.fastjson.JSON.parseObject(JSON.java:348) at com.alibaba.fastjson.JSON.parseObject(JSON.java:252) at com.alibaba.fastjson.JSON.parseObject(JSON.java:471) at net.gdface.facelog.CloneTest.test(CloneTest.java:56)

这应该是个bug,(我用版本的是1.2.38,就是支持java7的最后一个版本,再往后的版本都是java8编译的).跟踪了fastjson的源码,发现用于Exception的反序列化的ThrowableDeserializer代码中对于自定义成员反序列化的逻辑处理过于简单,只考虑了简单数据类型。 看了最新版本1.2.41对应代码,发现这个bug在1.2.41已经解决了,但1.2.41是java8编译的,因为我的项目编译对java版本的要求是java7,所以不能使用。所以这个问题,还得自己想办法解决。

我解决方法是绕开它,因为是在ThrowableDeserializer这里的代码出了问题,所以不能让fastjson以ThrowableDeserializer来实现 序列化和反序列化。

步骤1–序列化过程

将异常类型中需要序列化的字段序列化成一个简单的json string,这样在反序列化时fastjson就不会把它当做一个异常类型交给ThrowableDeserializer来处理。

    public String toJsonString(ServiceSecurityException exp){
        HashMap<String,Object> fields = new HashMap<String,Object>();
        fields.put("type", exp.getType());
        fields.put("deviceID", exp.getDeviceID());
        return JSON.toJSONString(fields);
    }

步骤2–反序列化

JSON.parseObject方法将上一步的json string 反序列化成一个JSONObject对象,

步骤3–反序列化

TypeUtils.castToJavaBean将上一步的JSONObject对象转换为指定的异常类型

代码实现如下:

String jsonStr = toJsonString(exp);
JSONObject obj = JSON.parseObject(jsonStr);
ServiceSecurityException newExp = TypeUtils.castToJavaBean(obj, ServiceSecurityException.class);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • LNK2019:win32下编写DLL,应用程序找不到DLL接口函数的一种情况

    版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net...

    用户1148648
  • fastjson:实现对java.nio.ByteBuffer数据类型的支持

    一般情况下,我们都用byte[]作为保存二进制数据的数据类型,较少用ByteBuffer来表示字节数组。然而最近的工作中需要二进制数据(字节数组)即支持fast...

    用户1148648
  • java:利用fastjson判断一个类型(java.lang.reflect.Type)是否是一个javabean

    fastjson中JSON.toJSON(Object javaObject)方法将一个java对象被序列化成json对象时,返回的对象类型有三种可能:JSON...

    用户1148648
  • 移动端轮播图

    星辰_大海
  • 【leetcode】背包问题

    完全背包的特点恰是每种物品可选无限件,所以就可以并且必须采用 w = W[i]…carry 的顺序循环:

    JNingWei
  • Python3 标准库概览

    本文基于以下教程: http://www.runoob.com/python3/python3-stdlib.html

    py3study
  • MFC中属性表单和向导对话框的使用

    每次在使用MFC创建一个框架时,需要一步步选择自己的程序的外观,基本功能等选项,最后MFC会生成一个基本的程序框架,这个就是向导对话框;而属性表单则是另外一种对...

    Masimaro
  • Android开发笔记(六十六)自定义对话框

    Android中最常用的对话框是AlertDialog,它可以完成常见的交互操作,如提示、确认、选择等等,然后就是进度对话框ProgressDialog(参...

    用户4464237
  • [答疑]人翻书,翻书的操作是在人上还是书上

    我有个问题,有个类书,一个类人,现在人想翻书,那么翻这个方法是放在书的类上,还是人的类上

    用户6288414
  • Ubuntu安装搜狗输入法

    初次使用Ubuntu系统的新手,肯定会遇到各种各样的问题,输入法的问题肯定没少折磨过大家,因为Ubuntu默认只有英文输入,没有中文输入。别着急,我马上就教大家...

    谭庆波

扫码关注云+社区

领取腾讯云代金券