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

问题描述:

持久层框架用的是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<User> users=new ArrayList<>();


    
@JsonManagedReference
public List<User> getUsers() {
    return users;
}

public void setUsers(List<User> users) {
    this.users = users;
}

发布了190 篇原创文章 · 获赞 8 · 访问量 71万+

猜你喜欢

转载自blog.csdn.net/Piconjo/article/details/105543615