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

前端之家收集整理的这篇文章主要介绍了修复fastjson启用WriteClassName时parse原生类型属性错误的bug前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

@seehttps://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,曲线救国,见代码

  1. /**
  2. * @author zzf
  3. */
  4. public class TObjectSerializer {
  5.  
  6. private static SerializeConfig serializeConfig = new SerializeConfig() {
  7. /**
  8. * private的变量,只能重新定义一把,开销不大。
  9. */
  10. private ASMSerializerFactory asmFactory;
  11. private boolean asm = !ASMUtils.isAndroid();
  12. {
  13. try {
  14. asmFactory = new ASMSerializerFactory();
  15. } catch (NoClassDefFoundError eror) {
  16. asm = false;
  17. } catch (ExceptionInInitializerError error) {
  18. asm = false;
  19. }
  20. }
  21.  
  22. public ObjectSerializer createJavaBeanSerializer(Class<?> clazz) {
  23. if (!Modifier.isPublic(clazz.getModifiers())) {
  24. return new JavaBeanSerializerX(clazz);
  25. }
  26.  
  27. boolean asm = this.asm;
  28.  
  29. if (asm && asmFactory.isExternalClass(clazz)
  30. || clazz == Serializable.class || clazz == Object.class) {
  31. asm = false;
  32. }
  33.  
  34. {
  35. JSONType annotation = clazz.getAnnotation(JSONType.class);
  36. if (annotation != null && annotation.asm() == false) {
  37. asm = false;
  38. }
  39. }
  40.  
  41. if (asm && !ASMUtils.checkName(clazz.getName())) {
  42. asm = false;
  43. }
  44.  
  45. if (asm) {
  46. try {
  47. ObjectSerializer asmSerializer = createASMSerializer(clazz);
  48. if (asmSerializer != null) {
  49. return asmSerializer;
  50. }
  51. } catch (ClassCastException e) {
  52. // skip
  53. } catch (Throwable e) {
  54. throw new JSONException(
  55. "create asm serializer error,class " + clazz,e);
  56. }
  57. }
  58.  
  59. return new JavaBeanSerializerX(clazz);
  60. }
  61.  
  62. class JavaBeanSerializerX extends JavaBeanSerializer {
  63. public JavaBeanSerializerX(Class<?> clazz) {
  64. super(clazz);
  65. }
  66.  
  67. public FieldSerializer createFieldSerializer(FieldInfo fieldInfo) {
  68. Class<?> clazz = fieldInfo.getFieldClass();
  69. /**
  70. * 修复android下的bug(非android下使用ASMSerializer,不报错)。
  71. *
  72. * 所有的努力都是为了这里,启用WriteClassName后,原生类型通过ObjectFieldSerializer(
  73. * javabean反射)取得的值是对应的对象,json串会加上对应类型后缀(L、F、D、S、B)。
  74. * 如果javabean使用原生类型定义变量,则反系列化parse时错误
  75. *
  76. * 在此修复bug:原生类型务必使用NumberFieldSerializer
  77. * (此类为包访问限制,只好复制一个NumberFieldSerializerX)
  78. *
  79. */
  80. if (clazz == Number.class || clazz == long.class || clazz == int.class
  81. || clazz == float.class || clazz == double.class
  82. || clazz == short.class || clazz == byte.class) {
  83. return new NumberFieldSerializerX(fieldInfo);
  84. }
  85.  
  86. return super.createFieldSerializer(fieldInfo);
  87. }
  88.  
  89. }
  90.  
  91. /**
  92. * copy NumberFieldSerializer
  93. */
  94. class NumberFieldSerializerX extends FieldSerializer {
  95.  
  96. public NumberFieldSerializerX(FieldInfo fieldInfo) {
  97. super(fieldInfo);
  98. }
  99.  
  100. public void writeProperty(JSONSerializer serializer,Object propertyValue) throws Exception {
  101. writePrefix(serializer);
  102. this.writeValue(serializer,propertyValue);
  103. }
  104.  
  105. @Override
  106. public void writeValue(JSONSerializer serializer,Object propertyValue) throws Exception {
  107. SerializeWriter out = serializer.getWriter();
  108.  
  109. Object value = propertyValue;
  110.  
  111. if (value == null) {
  112. if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) {
  113. out.write('0');
  114. } else {
  115. out.writeNull();
  116. }
  117. return;
  118. }
  119.  
  120. out.append(value.toString());
  121. }
  122. }
  123. };
  124.  
  125. public static byte[] serializeJSON(Object obj) throws IOException {
  126. return JSON.toJSONBytes(obj,serializeConfig,SerializerFeature.WriteClassName);
  127. }
  128.  
  129. public static Object deserializeJSON(byte[] data) throws IOException,ClassNotFoundException {
  130. return JSON.parse(data);
  131. }
  132. }

猜你在找的Json相关文章