1. 程式人生 > >jackson序列化json報錯java.lang.StackOverflowError

jackson序列化json報錯java.lang.StackOverflowError

工作中使用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即可。

學習:遇到比較底層的報錯式,如果在網上無法得出有用的資訊,可自己跟蹤下,找到具體發生錯誤的地方,其實報錯資訊那時候就比較明顯了。