HTTP 会话:如何配置不更改会话过期时间的 URL?

HTTP Session: how to configure URLs that not change the session expiration?

我的应用程序轮询每 5 分钟执行一次的 HTTP 请求。

我想将这些 URL 配置为不更改会话到期时间。 否则我的会话将永远不会过期(我不想要它)。 在 web.xml 和 HttpSession 文档中找不到它。

怎么可能呢?

已添加

非常重要的说明:应该对请求进行身份验证。 这意味着请求应该附加到已经通过身份验证的 JsessionID。

澄清(添加 2)

我不希望无论用户是否保持活动状态,会话都会过期。我希望会话将在用户不活动时过期,并且如果用户在 UI 上工作则不会过期。我希望会话将在用户不活动时过期,尽管每 5 分钟出现一次轮询请求

在您的情况下,您需要一个 Session 管理方案,无论用户是否保持活动状态,该方案都将在 N 分钟后过期。这样您就不需要绕过任何身份验证或默认 cookie。

您可以使用建议的两种方法来实现它here

  1. 一个计划作业,它在登录
  2. 后 N 分钟后使 session 无效
  3. 一种 Header 和基于过滤器的方法来动态决定 session 到期。

有很多方法可以做到这一点。其中之一是使用 javascript 例如 JQuery 。主要思想是不管脚本是否在轮询服务器,如果用户在应用程序上没有 activity 在合理的时间内(例如按键、鼠标移动等),则需要考虑用户不存在,javascript 需要为您的应用程序调用注销 url。请参考提供的URL,实际上很好地解释了这个概念。

标准 Servlet 不支持此功能 API。

您最好的选择是创建一个全局 servlet 过滤器(使用 @WebFilter("/*")),每次当特定 URL 访问服务器时减少 HttpSession#setMaxInactiveInterval(),并将其放回其他 URL 的默认值。它只需要一点基础数学。

实现的相关部分如下所示:

private static final int DEFAULT_EXPIRE_TIME_IN_SECONDS = 1800;
private static final String SKIP_EXPIRE_TIME_ON_URI = "/somePollServlet";

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpSession session = request.getSession();

    if (request.getRequestURI().equals(request.getContextPath() + SKIP_EXPIRE_TIME_ON_URI)) {
        long lastAccessedTime = session.getLastAccessedTime();
        long currentTime = System.currentTimeMillis();
        int newExpireTime = DEFAULT_EXPIRE_TIME_IN_SECONDS - (int) ((currentTime - lastAccessedTime) / 1000);
        session.setMaxInactiveInterval(newExpireTime);
    }
    else {
        session.setMaxInactiveInterval(DEFAULT_EXPIRE_TIME);
    }

    chain.doFilter(req, res);
}

这是@BalusC 的更新答案。他的解决方案并不完全适合我。试试这个解决方案。

@Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        int expireTimeInSeconds = 60;

        String skippableUrl = "/url";

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpSession session = request.getSession();

        int maxInactiveInterval = session.getMaxInactiveInterval();

        if (request.getRequestURI().equals(request.getContextPath() + skippableUrl )) {

            long lastAccessedTime = session.getLastAccessedTime();
            long currentTime = System.currentTimeMillis();
            int newMaxInactiveInterval = maxInactiveInterval - (int) ((currentTime - lastAccessedTime) / 1000);

            if (newMaxInactiveInterval <= 0 || maxInactiveInterval > expireTimeInSeconds) {
                session.invalidate();
            } else {
                session.setMaxInactiveInterval(newMaxInactiveInterval);
            }

        } else {
            session.setMaxInactiveInterval(expireTimeInSeconds);
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }