在与Tomcat 7.0上的Spring Web MVC一起运行的应用程序中,我有某些控制器,尽管对它们的请求将需要身份验证和有效的会话,但我不希望更新该会话的到期时间戳。换句话说,我希望会话在没有发生此特定HTTP请求的情况下完全过期。
如果重要的话,这些是AJAX方法,尽管我不知道是否有用。
可以通过通用Java EE或某些特殊的Tomcat挂钩完成此操作吗?还有另一种方法可以做到这一点吗?我知道http://download.oracle.com/javaee/6/api/javax/servlet/http/HttpSession.html#setMaxInactiveInterval%28int%29,但这似乎与我想要的相反。
访问 时间 仅 在访问 会话时更新HttpServletRequest#getSession。因此,如果您确定不篡改该会话,则应该可以。 更新: 基于JavaDoc,上述说法是不正确的(即使您彻底搜索了源代码,也没有找到造成这种行为的任何代码)。
HttpServletRequest#getSession
另一方面,如果您需要访问AJAX请求中的会话,那么您就很费力。我能想到的唯一解决方案是lastAccessTime手动存储(例如,在servlet过滤器中),然后检查会话超时并手动使会话无效(例如,在同一过滤器中)。那应该很简单并且易于实现。
lastAccessTime
更新: 仅出于乐趣,我实现了过滤器(未测试):
public class SessionInvalidationFilter implements Filter { private static final String LAST_ACCESS_SESSION_ATTR = "lastAccessTime"; private static final long SESSION_TIMEOUT = 1000 * 60 * 20; // 20 minutes private static final String IGNORE_ACCESS_URI = "/this/will-not/update/access-time"; @Override public void init(FilterConfig arg0) throws ServletException { } @Override public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // Cast to HTTP request and response HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // Check if we are handling standard request if (!IGNORE_ACCESS_URI.equals(httpRequest.getRequestURI())) { chain.doFilter(new SessionAccessAwareRequest(httpRequest), response); return; } // Now we can handle the special case of non-tracked request boolean expired = false; HttpSession session = httpRequest.getSession(false); if (session == null) { // No session means the AJAX contained no or incorrect JSESSIONID expired = true; } else { Long lastAccessTime = (Long) session.getAttribute(LAST_ACCESS_SESSION_ATTR); if (lastAccessTime == null || lastAccessTime + SESSION_TIMEOUT < System.currentTimeMillis()) { session.invalidate(); // Invalidate manually expired = true; } } // Handle error or process normally if (expired) { httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST); } else { chain.doFilter(request, response); } } private static class SessionAccessAwareRequest extends HttpServletRequestWrapper { public SessionAccessAwareRequest(HttpServletRequest request) { super(request); } @Override public HttpSession getSession() { return getSession(true); } @Override public HttpSession getSession(boolean create) { HttpSession session = super.getSession(create); if (session != null) { session.setAttribute(LAST_ACCESS_SESSION_ATTR, System.currentTimeMillis()); } return session; } } }