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