FastJson下抽象类的反序列化解决思路

背景

AResult A结果
BResult B结果
AbstractResult 结果基类


问题现象

在存入mongo时结果将会以List<AbstractResult> 序列化存入mongo,但是在取出结果时出现了问题。

通过mongo取出数据后,希望还原成为List<AbstractResult> ,于是通过反序列化来还原格式,此时出现问题,因为AbstractResult是抽象类,在进行反序列化时,无法反序列化成为对应的类。于是反序列化出来的List内元素全是null

解决思路一

通过网上查询有关FastJson抽象类反序列化的解决办法,只找到了一篇相关:https://www.cnblogs.com/549294286/p/8215109.html

本文的解决思路是编写ParserConfig类,类中复写getDeserializer(Type type)方法,并在JSON.parseObject时作为参数传入,该方法是用来根据类名来返回具体的反序列化方法的,通过复写该方法,在遇到Type为AbstractResult.class时,就可以返回指定的子类的反序列化方法,如

ParserConfig parserConfig = new ParserConfig() {
     @Override
     public ObjectDeserializer getDeserializer(Type type) {
            if (type == ActionConfig.class) {
                return super.getDeserializer(LimitActionConfig.class);
             }
             return super.getDeserializer(type);
     }
};

BResult方法或者AResult方法。尝试该解决思路,发现在整个list都是同一种子类时可以实现正常的反序列化,将整个List反序列化为AResult或者BResult。

解决思路二

上面的解决方法虽然能够成功,但是并不能解决实际遇到的问题,因为实际需要进行反序列化的List中的类型不是统一的,而是AResult和BResult同时存在的,所以必须有更加精确的反序列化方法。

网上没有类似问题的解决思路,于是只能翻阅源码查找解决思路。在查看了大量源码之后,找到了解决方案。

本解决方案借鉴了思路一的方法,在遇到Type为AbstractResult.class时,返回我自己编写的自定义的反序列化方法。代码如下

private static final ParserConfig parserConfig = new ParserConfig() {
    @Override
    public ObjectDeserializer getDeserializer(Type type) {
        if (type == AbstractResult.class) {
            return new AbstractResultDeserializer();
        }
        return super.getDeserializer(type);
    }
};


其中AbstractResultDeserializer的源码如下

public class AbstractResultDeserializer implements ObjectDeserializer {
    public static final String CHARACTERISTIC = "characteristic";
    @Override
    public <T> T deserialze(DefaultJSONParser parser, Type type, Object object) {
        String text = (String) parser.input; //需要反序列化的文本
        int begin = ((JSONScanner) parser.lexer).pos()+1;//当前反序列化进行到的位置
        text = text.substring(begin,findEndPoint(text,begin));
        if (text.contains(CHARACTERISTIC)){
            AbstractResult AResult = 
               parser.getConfig().getDeserializer(AResult.class).deserialze(parser,type, 
               object);
            return (T) AResult;
         }else {
            AbstractResult BResult =
               parser.getConfig().getDeserializer(BResult.class).deserialze(parser, 
               type, object);
            return (T) BResult;
         }
    }

   @Override
   public int getFastMatchToken() {
          return 0;
   }

   public static Integer findEndPoint(String text , int begin){
        int stack =0;
        int t;
        for (t = begin; t < text.length(); t++) {
            char ch = text.charAt(t);
            if (ch  == '{'){
                stack++;
            }
            if (ch == '}'){
                if (stack == 0){
                    break;
                }else {
                    stack--;
                }
            }
        }
        return t;
   }
}


自定义反序列化的具体反序列过程就是通过重写deserialze()方法实现,下面介绍一下方法内的变量和函数

CHARACTERISTIC AResult类中特有的变量名称

text  反序列化的总文本

begin List反序列化进行到的位置

findEndPoint()该函数能找到当前反序列化类在文本中的结束位置

该自定义反序列化主要逻辑为

1.从整体List需要反序列化的文本中分割出当前类的文本

2.判断文本中是否存在AResult类中特有的变量名称

3.若存在则调用AResult的反序列方法

4.若不存在则调用BResult的反序列方法

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在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进行泛型类反序列化的基本示例。当然,根据实际需求和数据结构的复杂程度,你可能需要进行更多的定制和处理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值