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

Wicket+Jetty:避免为存活探测请求创建新Http Session

解决Wicket 8探测端点创建多余HttpSession的问题

针对你的场景,以下几种方案可以彻底避免探测端点创建无效HttpSession,按推荐优先级排序:

方案一:容器级别为探测端点禁用会话跟踪(推荐)

直接在Jetty配置中为/probe/*路径禁用会话跟踪,从根源阻止Session创建。

方式1:通过web.xml配置

修改项目的web.xml,为探测端点对应的Wicket Servlet添加禁用会话跟踪的参数:

<servlet>
    <servlet-name>ProbeApplication</servlet-name>
    <servlet-class>org.apache.wicket.protocol.http.WicketServlet</servlet-class>
    <init-param>
        <param-name>applicationClassName</param-name>
        <param-value>你的包路径.WebApplicationProbe</param-value>
    </init-param>
    <!-- 核心配置:禁用会话跟踪 -->
    <init-param>
        <param-name>disableSessionTracking</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>ProbeApplication</servlet-name>
    <url-pattern>/probe/*</url-pattern>
</servlet-mapping>

方式2:通过Java代码配置Jetty

如果是用Java代码启动Jetty,在注册探测Servlet时添加禁用参数:

Server server = new Server();
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");

// 注册探测端点的Wicket Servlet
WicketServlet probeServlet = new WicketServlet();
ServletHolder probeHolder = new ServletHolder(probeServlet);
probeHolder.setInitParameter("applicationClassName", "你的包路径.WebApplicationProbe");
probeHolder.setInitParameter("disableSessionTracking", "true"); // 禁用会话跟踪
context.addServlet(probeHolder, "/probe/*");

server.setHandler(context);
server.start();

配置后,Jetty会对/probe/*路径的请求完全跳过会话跟踪逻辑,不会创建HttpSession,也不会返回带jsessionid的302跳转。

方案二:在Wicket探测应用中阻止Session创建

修改WebApplicationProbe,通过请求拦截告诉Jetty不要创建Session,同时调整Wicket自身的Session逻辑:

public class WebApplicationProbe extends WebApplication {   
    @Override 
    public Class<? extends WebPage> getHomePage() {
        return org.apache.wicket.util.tester.DummyHomePage.class;   
    }

    @Override
    protected void initRequestCycleListeners() {
        super.initRequestCycleListeners();
        addRequestCycleListener(new AbstractRequestCycleListener() {
            @Override
            public void onBeginRequest(RequestCycle cycle) {
                // 告诉Jetty不要为当前请求创建Session(Jetty特有属性)
                HttpServletRequest servletRequest = (HttpServletRequest) cycle.getRequest().getContainerRequest();
                servletRequest.setAttribute("org.eclipse.jetty.server.session.NoSession", Boolean.TRUE);
                
                // 同时让Wicket跳过Session相关初始化
                cycle.getRequest().setSessionAttribute("org.apache.wicket.Session", null);
            }
        });
    }

    @Override
    public void init() {
        super.init();
        // 关闭认证策略,避免Wicket触发Session创建
        getSecuritySettings().setAuthenticationStrategy(new NullAuthenticationStrategy());
        // 标记页面不需要Session支持
        getPageSettings().setRequireSession(false);
    }
}

方案三:请求结束后立即销毁Session(备选)

如果上述方案无法实施,可以在每个探测请求结束后立即销毁Session,避免长期积累:

public class WebApplicationProbe extends WebApplication {   
    // ... 原有代码 ...

    @Override
    protected void initRequestCycleListeners() {
        super.initRequestCycleListeners();
        addRequestCycleListener(new AbstractRequestCycleListener() {
            @Override
            public void onEndRequest(RequestCycle cycle) {
                // 销毁Wicket WebSession
                WebSession session = WebSession.get();
                if (session != null) {
                    session.invalidate();
                }
                // 销毁Jetty HttpSession
                HttpServletRequest servletRequest = (HttpServletRequest) cycle.getRequest().getContainerRequest();
                HttpSession httpSession = servletRequest.getSession(false);
                if (httpSession != null) {
                    httpSession.invalidate();
                }
            }
        });
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 17:42:10