工作中使用jackson序列化json到前台的时候,发现报错了
前台触发,后台直接卡死,部分堆栈如下
[ERROR][2017-07-03 09:35:37,148][org.framework.core.util.LogUtil][org.framework.web.system.listener.OnlineListener:sessionDestroyed():34] - java.lang.NullPointerException
[ERROR][2017-07-03 09:50:18,554][org.framework.core.common.exception.GlobalExceptionResolver]全局处理异常捕获:
java.lang.StackOverflowError
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:3196)
at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:1373)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1861)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1735)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:613)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:142)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:569)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:597)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:142)
跟踪代码调试,最终发现异常点在 org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
将最终异常粘贴出来,部分报错信息如下(不过基本全部是重复的)
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain:
org.framework.web.system.pojo.base.TSUserOrg["tsUser"]->com.moses.entity.mudcontacts.MudcontactsEntity["userOrgList"]->org.hibernate.collection.internal.PersistentBag[0]->
org.framework.web.system.pojo.base.TSUserOrg["tsUser"]->com.moses.entity.mudcontacts.MudcontactsEntity["userOrgList"]->org.hibernate.collection.internal.PersistentBag[0]->
org.framework.web.system.pojo.base.TSUserOrg["tsUser"]->com.moses.entity.mudcontacts.MudcontactsEntity["userOrgList"]->org.hibernate.collection.internal.PersistentBag[0]->
结合上述关键词,
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain:
就比较容易的搜到了解答方案,
根据如下博客将问题解决 http://blog.csdn.net/ludengji/article/details/11584281
A类中,有个属性:List<B> b, A与B的关系为 OneToMany;在B类中,有属性A a,引用到A中的字段id,并作为外键。hibernate查询结果正常,可以看到返回的A对象中,有b参数值,但在json转换的时候就出现了无限递归的情况。个人分析,应该是json在序列化A中的b属性的时候,找到了B类,然后序列化B类,而B类中有a属性,因此,为了序列化a属性,json又得去序列化A类,如此递归反复,造成该问题。
解决:
在B类中a的getter setter方法上加注解@JsonBackReference,其实自己试过只在setter方法上加@JsonBackReference也够了。
即在TSUserOrg的setTsUser上加注解@JsonBackReference即可。
学习:遇到比较底层的报错式,如果在网上无法得出有用的信息,可自己跟踪下,找到具体发生错误的地方,其实报错信息那时候就比较明显了。