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

添加Servlet过滤器后Java WebSocket会话未按指定时间超时的问题

WebSocket会话超时失效问题排查与解决

咱们来一步步分析为什么添加Servlet过滤器后WebSocket会话超时没触发,以及对应的解决办法:

1. 过滤器可能拦截并干扰了WebSocket握手请求

WebSocket的建立依赖HTTP握手请求(带有Upgrade: websocket头),如果你的过滤器对所有请求都做了统一处理,可能破坏了容器传递给WebSocket端点的超时配置。

解决办法:在过滤器中识别WebSocket握手请求,直接放行不做额外处理:

public class YourServletFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        // 判断是否为WebSocket握手请求
        if ("websocket".equalsIgnoreCase(httpRequest.getHeader("Upgrade"))) {
            chain.doFilter(request, response);
            return;
        }
        // 其他HTTP请求的过滤逻辑
        // ...
        chain.doFilter(request, response);
    }
}

2. 过滤器未开启异步支持

WebSocket握手属于异步HTTP请求,如果你的过滤器没有开启异步支持,容器无法正确维护WebSocket会话的生命周期,包括超时机制。

解决办法:

  • 若用注解配置过滤器,添加asyncSupported = true:
@WebFilter(urlPatterns = "/*", asyncSupported = true)
public class YourServletFilter implements Filter {
    // ...
}
  • 若用web.xml配置,添加<async-supported>true</async-supported>和异步Dispatcher映射:
<filter>
    <filter-name>YourServletFilter</filter-name>
    <filter-class>com.yourpackage.YourServletFilter</filter-class>
    <async-supported>true</async-supported>
</filter>
<filter-mapping>
    <filter-name>YourServletFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ASYNC</dispatcher>
</filter-mapping>

3. WebSocket会话超时配置未正确生效

即使过滤器没问题,也可能是你的WebSocket端点或容器的超时配置没有正确设置。

解决办法:

  • 在WebSocketConfigurator中显式设置会话超时:
public class WebSocketConfigurator extends ServerEndpointConfig.Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
        // 设置超时时间,示例为30分钟(单位:毫秒)
        config.getUserProperties().put("javax.websocket.session.timeout", 1800000);
        super.modifyHandshake(config, request, response);
    }
}
  • 检查容器全局配置:比如Tomcat可在server.xml的<Connector>中添加websocketTimeout="1800000";WebLogic则需在控制台配置WebSocket超时参数。

4. 过滤器持有会话引用导致无法回收

如果过滤器中存在静态变量或长生命周期对象持有WebSocket Session或HttpSession的引用,会导致容器无法触发超时回收逻辑。

解决办法:排查过滤器代码,确保没有不必要地缓存会话对象,尤其是避免在静态字段中存储会话引用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:08:50