加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

fastjson 解析多级泛型时而失败的解决方案

发布时间:2020-12-16 18:54:00 所属栏目:百科 来源:网络整理
导读:fastjson 解析多级泛型时而失败: class PeiqiResponse T { Boolean success; Integer errCode; String errDes; T result;} 声明: PeiqiResponseListDept 调试分析 经过多次调试,问题出现在这里 DefaultFieldDeserializer#parseField @Override public voi

fastjson 解析多级泛型时而失败:

class PeiqiResponse<T> {

    Boolean success;
    Integer errCode;
    String  errDes;
    T       result;
}

声明:PeiqiResponse<List<Dept>>

调试分析

经过多次调试,问题出现在这里 DefaultFieldDeserializer#parseField

@Override
    public void parseField(DefaultJSONParser parser,Object object,Type objectType,Map<String,Object> fieldValues) {
        if (fieldValueDeserilizer == null) {
            getFieldValueDeserilizer(parser.getConfig());
        }

if (objectType instanceof ParameterizedType) {
            ParseContext objContext = parser.getContext();
            objContext.type = objectType;
            fieldType = FieldInfo.getFieldType(this.clazz,objectType,fieldType);
 }

如我的对象类型 result 的类型是 List,但是经过 getFieldValueDeserilizer(parser.getConfig()) 的处理后 fieldValueDeserilizer ==JavaObjectDeserializer,然后在 68行 进行解析处理

68  value = fieldValueDeserilizer.deserialze(parser,fieldType,fieldInfo.name);

接着分析 JavaObjectDeserializer

public <T> T deserialze(DefaultJSONParser parser,Type type,Object fieldName) {
        if (type instanceof GenericArrayType) {
            Type componentType = ((GenericArrayType) type).getGenericComponentType();
            if (componentType instanceof TypeVariable) {
                TypeVariable<?> componentVar = (TypeVariable<?>) componentType;
                componentType = componentVar.getBounds()[0];
            }

            List<Object> list = new ArrayList<Object>();
            parser.parseArray(componentType,list);
            Class<?> componentClass;
            if (componentType instanceof Class) {
                componentClass = (Class<?>) componentType;
                Object[] array = (Object[]) Array.newInstance(componentClass,list.size());
                list.toArray(array);
                return (T) array;
            } else {
                return (T) list.toArray();
            }

        }

        if (type instanceof Class && type != Object.class && type != Serializable.class) {
            return (T) parser.parSEObject(type); 
        }

        return (T) parser.parse(fieldName);//最后到了这里,
       //而 parser == DefaultJSONParser (来源于 `DefaultJSONParser (614) return (T) derializer.deserialze(this,type,fieldName);`)
    }

然后进入 DefaultJSONParser 1280 行 parse(Object fieldName) ,在这里就将result的值解析成了 JSONArray对象,从而造成类型转换错误,没有得到预期的类型。

解决方案

回到来这里 DefaultFieldDeserializer#parseField

@Override
    public void parseField(DefaultJSONParser parser,fieldType);
 }

既然是多级泛型 ParameterizedType 并且解析除了泛型类型 fieldType ,为什么不加一行

fieldValueDeserilizer = parser.getConfig().getDeserializer(fieldType)

这样从我贴的数据中就得到了 fieldValueDeserilizer = CollectionCodec,这样就根据 fieldType获取到了正确的 fieldValueDeserilizer

Issues:
- https://github.com/alibaba/fastjson/issues/569

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读