如果用户单击浏览器后退按钮,则会话期满后如何将用户移动到超时页面 [英] How to move user to timeout page when session expires, if user click on browser back button

查看:112
本文介绍了如果用户单击浏览器后退按钮,则会话期满后如何将用户移动到超时页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用filter处理JSF 2.0中的会话到期.这是代码

I am handling session expiration in JSF 2.0 using filter . Here is the code

  @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()

但是问题是,当会话过期时,如果用户单击后退"按钮,那么他将获得所有样式的页面.无论如何,当会话终止时,如果用户单击浏览器的后退"按钮,则他将定向到timeoutPage.

But the problem is, when session expires and if user click on the back button, then he gets the page with all styling out. Is there is anyway that when session expires, and if user click the browser back button, then he directs to the timeoutPage.

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

One thing more, that i am also using Prime Faces component on my page, like datatable. I am using pagination. If session time out, and i click on pagination then the session expiration message do not appear. It seems that ajax request don't call filter? How can i connect my ajax events, or you can say datatable pagination events to session expiration?

谢谢

推荐答案

会话期满后,如果用户单击后退"按钮,则他将获得所有样式均已显示的页面

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

You need to tell the browser to not cache the pages in browser cache. The browser shoud instead be sending a full request to the server.

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

Add the following lines right before filterChain.doFilter() call.

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请求不调用过滤器?

JSF ajax请求期望XML响应的HTTP状态为200.如果发送同步重定向,则将发送HTTP状态302响应,JSF ajax引擎将完全忽略该响应.您应该发送带有特定XML的正常HTTP 200响应,该响应告诉JSF ajax引擎执行重定向.代替httpServletResponse.sendRedirect()然后执行此操作:

JSF ajax requests expect XML responses with HTTP status 200. If you send a synchronous redirect, then a HTTP status 302 response will be sent which will be completely ignored by JSF ajax engine. You should instead be sending a normal HTTP 200 response with a specific piece of XML which tells the JSF ajax engine to perform a redirect. Do this instead of httpServletResponse.sendRedirect() then:

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()方法.它将相应地透明地处理同步/异步请求.

Note that when you're already inside JSF context (e.g. by PhaseListener or SystemEventListener or maybe a @ManagedBean), then you could just use ExternalContext#redirect() method. It will transparently handle synchronous/asynchronous requests accordingly.

这篇关于如果用户单击浏览器后退按钮,则会话期满后如何将用户移动到超时页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆