背景
AResult A结果
BResult B结果
AbstractResult 结果基类
问题现象
在存入mongo时结果将会以List<AbstractResult> 序列化存入mongo,但是在取出结果时出现了问题。
通过mongo取出数据后,希望还原成为List<AbstractResult> ,于是通过反序列化来还原格式,此时出现问题,因为AbstractResult是抽象类,在进行反序列化时,无法反序列化成为对应的类。于是反序列化出来的List内元素全是null
解决思路一
通过网上查询有关FastJson抽象类反序列化的解决办法,只找到了一篇相关:/549294286/p/
本文的解决思路是编写ParserConfig类,类中复写getDeserializer(Type type)方法,并在时作为参数传入,该方法是用来根据类名来返回具体的反序列化方法的,通过复写该方法,在遇到Type为时,就可以返回指定的子类的反序列化方法,如
ParserConfig parserConfig = new ParserConfig() {
@Override
public ObjectDeserializer getDeserializer(Type type) {
if (type == ) {
return ();
}
return (type);
}
};
BResult方法或者AResult方法。尝试该解决思路,发现在整个list都是同一种子类时可以实现正常的反序列化,将整个List反序列化为AResult或者BResult。
解决思路二
上面的解决方法虽然能够成功,但是并不能解决实际遇到的问题,因为实际需要进行反序列化的List中的类型不是统一的,而是AResult和BResult同时存在的,所以必须有更加精确的反序列化方法。
网上没有类似问题的解决思路,于是只能翻阅源码查找解决思路。在查看了大量源码之后,找到了解决方案。
本解决方案借鉴了思路一的方法,在遇到Type为时,返回我自己编写的自定义的反序列化方法。代码如下
private static final ParserConfig parserConfig = new ParserConfig() {
@Override
public ObjectDeserializer getDeserializer(Type type) {
if (type == ) {
return new AbstractResultDeserializer();
}
return (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) ; //需要反序列化的文本
int begin = ((JSONScanner) ).pos()+1;//当前反序列化进行到的位置
text = (begin,findEndPoint(text,begin));
if ((CHARACTERISTIC)){
AbstractResult AResult =
().getDeserializer().deserialze(parser,type,
object);
return (T) AResult;
}else {
AbstractResult BResult =
().getDeserializer().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 < (); t++) {
char ch = (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的反序列方法