修复fastjson启用WriteClassName时parse原生类型属性错误的bug

来源:互联网 发布:法拉克系统编程实例 编辑:程序博客网 时间:2024/05/16 18:22

@see https://github.com/alibaba/fastjson/issues/288

fastjson启用WriteClassName后,在android下,若javabean中定义了原生类型(long short double float short byte),

则系列化后json格式中将包含其对象类型的后缀(L S D F S B),导致parse时格式解析错误。


为了修复JavaBeanSerializer#createFieldSerializer,曲线救国,见代码:

/** * @author zzf */public class TObjectSerializer {private static SerializeConfig serializeConfig = new SerializeConfig() {/** * private的变量,只能重新定义一把,开销不大。 */private ASMSerializerFactory asmFactory;private boolean asm = !ASMUtils.isAndroid();{try {asmFactory = new ASMSerializerFactory();} catch (NoClassDefFoundError eror) {asm = false;} catch (ExceptionInInitializerError error) {asm = false;}}public ObjectSerializer createJavaBeanSerializer(Class<?> clazz) {if (!Modifier.isPublic(clazz.getModifiers())) {return new JavaBeanSerializerX(clazz);}boolean asm = this.asm;if (asm && asmFactory.isExternalClass(clazz)|| clazz == Serializable.class || clazz == Object.class) {asm = false;}{JSONType annotation = clazz.getAnnotation(JSONType.class);if (annotation != null && annotation.asm() == false) {asm = false;}}if (asm && !ASMUtils.checkName(clazz.getName())) {asm = false;}if (asm) {try {ObjectSerializer asmSerializer = createASMSerializer(clazz);if (asmSerializer != null) {return asmSerializer;}} catch (ClassCastException e) {// skip} catch (Throwable e) {throw new JSONException("create asm serializer error, class " + clazz, e);}}return new JavaBeanSerializerX(clazz);}class JavaBeanSerializerX extends JavaBeanSerializer {public JavaBeanSerializerX(Class<?> clazz) {super(clazz);}public FieldSerializer createFieldSerializer(FieldInfo fieldInfo) {Class<?> clazz = fieldInfo.getFieldClass();/** * 修复android下的bug(非android下使用ASMSerializer,不报错)。 *  * 所有的努力都是为了这里,启用WriteClassName后,原生类型通过ObjectFieldSerializer( * javabean反射)取得的值是对应的对象,json串会加上对应类型后缀(L、F、D、S、B)。 * 如果javabean使用原生类型定义变量,则反系列化parse时错误。 *  * 在此修复bug:原生类型务必使用NumberFieldSerializer * (此类为包访问限制,只好复制一个NumberFieldSerializerX) *  */if (clazz == Number.class || clazz == long.class || clazz == int.class|| clazz == float.class || clazz == double.class|| clazz == short.class || clazz == byte.class) {return new NumberFieldSerializerX(fieldInfo);}return super.createFieldSerializer(fieldInfo);}}/** * copy NumberFieldSerializer */class NumberFieldSerializerX extends FieldSerializer {public NumberFieldSerializerX(FieldInfo fieldInfo) {super(fieldInfo);}public void writeProperty(JSONSerializer serializer,Object propertyValue) throws Exception {writePrefix(serializer);this.writeValue(serializer, propertyValue);}@Overridepublic void writeValue(JSONSerializer serializer,Object propertyValue) throws Exception {SerializeWriter out = serializer.getWriter();Object value = propertyValue;if (value == null) {if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) {out.write('0');} else {out.writeNull();}return;}out.append(value.toString());}}};public static byte[] serializeJSON(Object obj) throws IOException {return JSON.toJSONBytes(obj, serializeConfig,SerializerFeature.WriteClassName);}public static Object deserializeJSON(byte[] data) throws IOException,ClassNotFoundException {return JSON.parse(data);}}



0 0
原创粉丝点击