关于数据序列化(4),FastJson的两个bug

前端之家收集整理的这篇文章主要介绍了关于数据序列化(4),FastJson的两个bug前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

bug1 fastJson循环引用引发一个bug

fastJson可以将一个对象序列化为json,也可以通过反序列化出一个完整的对象。且支持循环引用。

  1. package com.sincetimes.website.core.common.support;
  2.  
  3. import com.sincetimes.website.core.common.vo.ToStringAbstract;
  4.  
  5. /** ::new */
  6. public class DataSimpleVO {
  7. public String name;
  8. public Object value;
  9. public Object value1;
  10.  
  11. public DataSimpleVO() {
  12. }
  13.  
  14. public DataSimpleVO(String name,Object value) {
  15. this.name = name;
  16. this.value = value;
  17. }
  18.  
  19. @Override
  20. public String toString() {
  21. return "DataSimpleVO [name=" + name + ",value=" + value + ",value1=" + value1 + "]";
  22. }
  23.  
  24. }
  1. DataSimpleVO a = new DataSimpleVO("a",1);
  2. DataSimpleVO b = new DataSimpleVO("b",2);
  3. b.value = a;
  4. Map<String,Object> map = new HashMap<>();
  5. map.put(a.name,a);
  6. b.value1 = map;
  7. String jsonStr = JSON.toJSONString(b);
  8. System.out.println(jsonStr);
  9. DataSimpleVO obj = JSON.parSEObject(jsonStr,DataSimpleVO.class);
  10. System.out.println(obj.toString());

执行结果

  1. {"name":"b","value":{"name":"a","value":1},"value1":{"a":{"$ref":"$.value"}}}
  2. DataSimpleVO [name=b,value={"name":"a",value1={"a":{"name":"a","value":1}}]

反序列化成功

改一下代码

  1. DataSimpleVO a = new DataSimpleVO("a",2);
  2. b.value1 = a;
  3. Map<String,a);
  4. b.value = map;
  5. String jsonStr = JSON.toJSONString(b);
  6. System.out.println(jsonStr);
  7. DataSimpleVO obj = JSON.parSEObject(jsonStr,"value":{"a":{"name":"a","value":1}},"value1":{"$ref":"$.value.a"}}
  8. DataSimpleVO [name=b,value={"a":{"name":"a",value1=null]

b中的value1为空,反序列化失败

bug2 要序列化的类含有Class类型属性引起的循环递归无法结束最后内存溢出

要序列化、反序列化的类

  1. public class Request implements Serializable {
  2.  
  3. private static final long serialVersionUID = -3145939364922415428L;
  4.  
  5. private Class<?> clazz;
  6.  
  7. private String method;
  8.  
  9. private Object param;
  10.  
  11. public Class<?> getClazz() {
  12. return clazz;
  13. }
  14.  
  15. public void setClazz(Class<?> clazz) {
  16. this.clazz = clazz;
  17. }
  18.  
  19. public String getMethod() {
  20. return method;
  21. }
  22.  
  23. public void setMethod(String method) {
  24. this.method = method;
  25. }
  26.  
  27. public Object getParam() {
  28. return param;
  29. }
  30.  
  31. public void setParam(Object param) {
  32. this.param = param;
  33. }
  34.  
  35. public Object invoke(Object bean) throws Exception {
  36. return clazz.getMethod(method,param.getClass()).invoke(bean,param);
  37. }
  38. }

触发bug

  1. Request r = new Request();
  2. r.setClazz(Integer.class);
  3. String s = JSON.toJSONString(r,SerializerFeature.WriteClassName);
  4. System.out.println(s);
  5. JSON.parSEObject(s);//bug 触发

我们看看内部

  1. public static JSONObject parSEObject(String text) {
  2. Object obj = parse(text);
  3. if (obj instanceof JSONObject) {
  4. return (JSONObject) obj;
  5. }
  6.  
  7. return (JSONObject) JSON.toJSON(obj);
  8. }

如果改为JSON.parSEObject(s,Request.class);或者直接使用JSON.parse(str)就没问题。

最后的建议: 不要使用JSON.parSEObject(…)只使用JSON.parse(str);

猜你在找的Json相关文章