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
相关产品推荐
相关产品推荐

