如果用户单击浏览器后退按钮,如何在会话到期时将用户移动到超时页面

时间:2012-03-19 07:14:08

标签: jsf-2

我正在使用过滤器处理JSF 2.0中的会话过期。这是代码

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

    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;

    HttpSession session = httpServletRequest.getSession(false);

    if (session == null) {

        //session timeout check.
        if (httpServletRequest.getRequestedSessionId() != null && !httpServletRequest.isRequestedSessionIdValid()) {

            System.out.println("Session has expired");
            session = httpServletRequest.getSession(true);
            session.setAttribute("logedin", "0");    // public user               
            httpServletResponse.sendRedirect(timeoutPage);

        } else {

            session = httpServletRequest.getSession(true);
            session.setAttribute("logedin", "0");
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        }
    } 
} //end of doFilter()

但问题是,当会话过期并且用户点击后退按钮时,他会获得所有样式的页面。无论如何,当会话到期时,如果用户点击浏览器后退按钮,那么他将指向超时页面。

还有一点,我也在我的页面上使用Prime Faces组件,比如datatable。我正在使用分页。如果会话超时,并且我单击分页,则不会出现会话到期消息。似乎ajax请求不调用过滤器?如何连接我的ajax事件,或者你可以说数据表分页事件到会话到期?

谢谢

1 个答案:

答案 0 :(得分:5)

  

当会话过期时,如果用户点击后退按钮,那么他会获得所有样式的页面

您需要告诉浏览器不要将页面缓存在浏览器缓存中。浏览器应该向服务器发送完整的请求。

在调用filterChain.doFilter()之前添加以下行。

if (!httpServletRequest.getRequestURI().startsWith(httpServletRequest.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
    httpServletResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
    httpServletResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0.
    httpServletResponse.setDateHeader("Expires", 0); // Proxies.
}

  

如果会话超时,我点击分页,则不会出现会话过期消息。似乎ajax请求不会调用filter?

JSF ajax请求期望HTTP状态为200的XML响应。如果发送同步重定向,则将发送HTTP状态302响应,JSF ajax引擎将完全忽略该响应。您应该使用特定的XML发送正常的HTTP 200响应,该响应告诉JSF ajax引擎执行重定向。这样做而不是httpServletResponse.sendRedirect()然后:

if ("partial/ajax".equals(httpServletRequest.getHeader("Faces-Request"))) {
    httpServletResponse.setContentType("text/xml");
    httpServletResponse.getWriter()
        .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
        .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", timeoutPage);
}
else {
    httpServletResponse.sendRedirect(timeoutPage);
}

请注意,当您已经在JSF上下文中时(例如,通过PhaseListenerSystemEventListener@ManagedBean),您可以使用ExternalContext#redirect()方法。它将相应地透明地处理同步/异步请求。