解决返回JSON报错:HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowE

Jane ·
更新时间:2024-11-13
· 630 次阅读

问题描述:

持久层框架用的是JPA

在Controller返回JSON数据到前端的时候 出现了这个StackOverflowError的错误
即 在将对象转换为JSON格式的数据的时候出现了无限递归调用的情况

如下:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]->net.zjitc.xxx.pojo.XXX["XXX"]->org.hibernate.collection.internal.PersistentBag[0]->net.zjitc.xxx.pojo.XXX["XXX"]) at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:296) at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:103) at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:180) at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 原因:

实体类之间互相关联 在序列化A实体类的时候 由于A里有B类 然后去序列化B 在序列化B实体类的时候 又由于B里有A类 然后去序列化A
如此反复递归 从而造成该问题

解决方法:

在有关联关系的属性的getter方法(请注意 是getter方法不是setter方法)上添加@JsonBackReference@JsonManagedReference注解

的一方加上@JsonBackReference注解 并且在的一方加上@JsonManagedReference注解

这两个注解通常是配对使用的
@JsonBackReference注解标注的属性在序列化(serialization)的时候会被忽略 即结果中的json数据不包含该属性的内容
@JsonManagedReference注解标注的属性则会被序列化

例一:

@ManyToOne private Type type; @JsonBackReference public Type getType() { return type; } public void setType(Type type) { this.type = type; }

例二:

@OneToMany(mappedBy = "type") private List users=new ArrayList(); @JsonManagedReference public List getUsers() { return users; } public void setUsers(List users) { this.users = users; }
作者:Piconjo_Official



JSON write infinite

需要 登录 后方可回复, 如果你还没有账号请 注册新账号