You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring ResponseEntity返回含HttpSession的Token时触发StackOverflow错误

问题:Spring MVC返回含HttpSession的Token对象时出现StackOverflowError

我在Spring MVC的Rest控制器方法里,尝试把包含HttpSession对象的自定义Token类通过ResponseEntity返回给客户端。但只要Token类里有HttpSession属性,就会因为Jackson数据绑定的无限递归问题触发StackOverflow错误;如果去掉这个属性就完全正常。

我的Token类代码:

public class Token implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private HttpSession session; 
    private String value; 

    public Token () {} 

    public Token (HttpSession session, String value) { 
        this.session = session; 
        this.value = value; 
    } 

    public String getValue() { return value; } 
    public void setValue(String value) { this.value = value; } 
    public HttpSession getSession() { return session; } 
    public void setSession(HttpSession session) { this.session = session; } 
}

控制器方法代码:

@RequestMapping(value = "/getData", method = RequestMethod.GET) 
public ResponseEntity<Token> getData(HttpServletRequest request) { 
    HttpSession session = request.getSession(); 
    Token t = new Token(session, "value"); 
    return new ResponseEntity<Token>(t, HttpStatus.OK); 
}

堆栈跟踪的核心信息:

Root cause of ServletException. 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: weblogic.servlet.internal.WebAppServletContext["securityContext"]->weblogic.servlet.internal.ServletSecurityContextImpl["servletContext"]............... com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) at ........-

请问出现该问题的原因是什么?


原因分析

这个问题的核心在于Jackson在序列化HttpSession对象时触发了无限递归引用,具体可以拆解为这几点:

  1. HttpSession内部的引用闭环
    从堆栈里的weblogic.servlet.internal相关类能看出来,你使用的WebLogic容器实现的HttpSession,内部持有对ServletContext的引用,而ServletContext又反过来引用了SecurityContext,SecurityContext再次指向ServletContext——形成了一个无法打断的引用循环。当Jackson尝试递归序列化这些对象的所有属性时,会一直在这个闭环里循环,直到栈内存耗尽,抛出StackOverflowError。

  2. Jackson默认序列化规则的局限
    Jackson默认会通过对象的getter方法序列化所有可访问属性,Token类里的getSession()方法会让Jackson尝试完整序列化HttpSession实例。但HttpSession是Web容器管理的核心服务器端对象,它本身就不是为序列化成JSON设计的,内部包含大量容器上下文的关联对象,引用关系极其复杂,很容易出现循环引用。

  3. 不合理的序列化对象选择
    另外,虽然你的Token类实现了Serializable,但HttpSession本身就是不能被安全序列化到客户端的对象——它是服务器端维护的会话标识,包含服务器上下文、会话状态等敏感且无法在客户端复用的内容,强行把它返回给客户端本身就是不符合设计逻辑的。

简单来说,你试图把一个服务器端的核心会话对象直接返回给客户端,Jackson在序列化它的时候陷入了无限循环,最终导致栈溢出。


内容的提问来源于stack exchange,提问作者Kingamere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:06:06