bug1 fastJson循环引用引发一个bug
fastJson可以将一个对象序列化为json,也可以通过反序列化出一个完整的对象。且支持循环引用。
- package com.sincetimes.website.core.common.support;
-
- import com.sincetimes.website.core.common.vo.ToStringAbstract;
-
- /** ::new */
- public class DataSimpleVO {
- public String name;
- public Object value;
- public Object value1;
-
- public DataSimpleVO() {
- }
-
- public DataSimpleVO(String name,Object value) {
- this.name = name;
- this.value = value;
- }
-
- @Override
- public String toString() {
- return "DataSimpleVO [name=" + name + ",value=" + value + ",value1=" + value1 + "]";
- }
-
- }
- DataSimpleVO a = new DataSimpleVO("a",1);
- DataSimpleVO b = new DataSimpleVO("b",2);
- b.value = a;
- Map<String,Object> map = new HashMap<>();
- map.put(a.name,a);
- b.value1 = map;
- String jsonStr = JSON.toJSONString(b);
- System.out.println(jsonStr);
- DataSimpleVO obj = JSON.parSEObject(jsonStr,DataSimpleVO.class);
- System.out.println(obj.toString());
执行结果
- {"name":"b","value":{"name":"a","value":1},"value1":{"a":{"$ref":"$.value"}}}
- DataSimpleVO [name=b,value={"name":"a",value1={"a":{"name":"a","value":1}}]
反序列化成功
改一下代码
- DataSimpleVO a = new DataSimpleVO("a",2);
- b.value1 = a;
- Map<String,a);
- b.value = map;
- String jsonStr = JSON.toJSONString(b);
- System.out.println(jsonStr);
- DataSimpleVO obj = JSON.parSEObject(jsonStr,"value":{"a":{"name":"a","value":1}},"value1":{"$ref":"$.value.a"}}
- DataSimpleVO [name=b,value={"a":{"name":"a",value1=null]
b中的value1为空,反序列化失败
bug2 要序列化的类含有Class类型属性引起的循环递归无法结束最后内存溢出
要序列化、反序列化的类
- public class Request implements Serializable {
-
- private static final long serialVersionUID = -3145939364922415428L;
-
- private Class<?> clazz;
-
- private String method;
-
- private Object param;
-
- public Class<?> getClazz() {
- return clazz;
- }
-
- public void setClazz(Class<?> clazz) {
- this.clazz = clazz;
- }
-
- public String getMethod() {
- return method;
- }
-
- public void setMethod(String method) {
- this.method = method;
- }
-
- public Object getParam() {
- return param;
- }
-
- public void setParam(Object param) {
- this.param = param;
- }
-
- public Object invoke(Object bean) throws Exception {
- return clazz.getMethod(method,param.getClass()).invoke(bean,param);
- }
- }
触发bug
- Request r = new Request();
- r.setClazz(Integer.class);
- String s = JSON.toJSONString(r,SerializerFeature.WriteClassName);
- System.out.println(s);
- JSON.parSEObject(s);//bug 触发
我们看看内部
- public static JSONObject parSEObject(String text) {
- Object obj = parse(text);
- if (obj instanceof JSONObject) {
- return (JSONObject) obj;
- }
-
- return (JSONObject) JSON.toJSON(obj);
- }
如果改为JSON.parSEObject(s,Request.class);或者直接使用JSON.parse(str)就没问题。
最后的建议: 不要使用JSON.parSEObject(…)只使用JSON.parse(str);