fasterxml 循环引用导致*Error线程栈错误
有时候,需要将对象json串化,转换成字符串,便于前后端数据传输,或者多平台系统交互。但一不小心,待转换成json串的对象,居然引用到系统对象,比如Spring系统对象RequestContext,然后重量级对象,数据结构是相当复杂的,各种繁杂的对象相互引用,那必然会出现递归寻找。
错误案例一:
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (*Error) (through reference chain: java.util.LinkedHashMap["springMacroRequestContext"]->org.springframework.web.servlet.support.RequestContext["model"]->java.util.LinkedHashMap["springMacroRequestContext"]->org.springframework.web.servlet.support.RequestContext["model"]-
……此处省略一大堆
Caused by: java.lang.*Error: null
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_91]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_91]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_91]
错误案例二:
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (*Error) (through reference chain: StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]->StuClass["stus"]->java.util.ArrayList[0]->Student["stuClass"]-
……此处省略一大堆
Caused by: java.lang.*Error: null
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_91]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_91]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_91]
来一段手动制造的循环引用,学生Student 引用 班级StuClass,班级StuClass里再引用Student。如下图:
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
/**
* Created by changle on 16/10/26.
*/
@Slf4j
public class TestCommon {
private static final ObjectMapper mapper = new ObjectMapper();
@Data
static class StuClass {
String name;
Integer pepoleNum;
List<Student> stus;
}
@Data
static class Student {
String name;
StuClass stuClass;
}
public static void main(String[] args){
Student student = new Student();
student.setName("张三");
StuClass stuClass = new StuClass();
stuClass.setName("高三(一)班");
stuClass.setPepoleNum(50);
stuClass.setStus(new ArrayList<>());
stuClass.getStus().add(student);
student.setStuClass(stuClass);
log.info(getJsonStr(student));
}
private static<T> String getJsonStr(T o){
String result = "";
try {
result = mapper.writeValueAsString(o);
} catch (Exception e) {
log.error("getJsonStr(T o) happened error! ",e);
}
return result;
}
}
上图必抛*Error错误!
原因很清楚: 被序列化的对象引用了复杂大对象或本身出现相互引用,最终导致线程栈嵌套层次太深,抛出*Error
上一篇: 上大学学学习,上班班用不到
下一篇: HttpServletRequest接口