通过fastjson反序列化某javabean时失败,并抛出以下异常:
Could not deserialize: autoType is not support. com.xxx.Shop; nested exception is com.alibaba.fastjson.JSONException: autoType is not support. com.xxx.Shop at com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer.deserialize(GenericFastJsonRedisSerializer.java:37)
然而只有项目第一次反序列化该javabean时会抛异常失败,复现方式只有重启项目后的第一次反序列化操作。 过程
查询官方文档,开启AutoType的方法 enable_autotype。
但是文档中的方法均测试无效,无奈debug源码,发现抛出异常的代码为 com.alibaba.fastjson.parser.ParserConfig的1125行代码:
JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, clazz, propertyNamingStrategy); if (beanInfo.creatorConstructor != null && autoTypeSupport) { throw new JSONException("autoType is not support. " + typeName); }
经与正常反序列化的javabean比较后,发现反序列化失败的javabean在如上代码执行时,beanInfo.creatorConstructor的值不为null,最后抛出autoType is not support的异常。
继续追踪,在com.alibaba.fastjson.util.JavaBeanInfo283行代码判断反序列化失败的javabean为接口或抽象类:
boolean isInterfaceOrAbstract = clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers());
再于com.alibaba.fastjson.util.JavaBeanInfo381行代码的if判断分支下给beanInfo.creatorConstructor赋值:
else if (!isInterfaceOrAbstract){ ... for (Constructor constructor : constructors) { Class[] parameterTypes = constructor.getParameterTypes(); if (className.equals("org.springframework.security.web.authentication.WebAuthenticationDetails")) { if (parameterTypes.length == 2 && parameterTypes[0] == String.class && parameterTypes[1] == String.class) { creatorConstructor = constructor; creatorConstructor.setAccessible(true); paramNames = ASMUtils.lookupParameterNames(constructor); break; } } if (className.equals("org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken")) { if (parameterTypes.length == 3 && parameterTypes[0] == Object.class && parameterTypes[1] == Object.class && parameterTypes[2] == Collection.class) { creatorConstructor = constructor; creatorConstructor.setAccessible(true); paramNames = new String[] {"principal", "credentials", "authorities"}; break; } } if (className.equals("org.springframework.security.core.authority.SimpleGrantedAuthority")) { if (parameterTypes.length == 1 && parameterTypes[0] == String.class) { creatorConstructor = constructor; paramNames = new String[] {"authority"}; break; } } boolean is_public = (constructor.getModifiers() & Modifier.PUBLIC) != 0; if (!is_public) { continue; } String[] lookupParameterNames = ASMUtils.lookupParameterNames(constructor); if (lookupParameterNames == null || lookupParameterNames.length == 0) { continue; } if (creatorConstructor != null && paramNames != null && lookupParameterNames.length
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?