2013-07-23 55 views
0

我对JSF 2.0中的会话管理方式感到困惑。JSF 2.0中的会话管理

我创建了4页登录,数据,信息和sessionexpires,显示会话已过期。

当我点击退出按钮,它通过调用下面的操作方法失效会话:

public String logout(){ 
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); 
    return "logout?faces-redirect=true"; 
} 

代码重定向我注销页,符合市场预期,但是当我点击浏览器的后退按钮,它需要我数据页面并显示所有信息,但我认为,如果会话已过期,则应显示sessionexpires页面。

如何实现所需的功能?

+0

[避免JSF Web应用程序上的后退按钮](http:// stackoverflow。com/questions/10305718/avoid-back-button-on-jsf-web-application) – BalusC

+0

非常感谢@BalusC,但我的问题仍然不是在单击后退按钮上完全缓存页面,而是在缓存页面上,为什么在点击时执行操作的命令按钮,如果我无效的会话 –

回答

3

当用户单击浏览器的后退按钮时,您会看到上一页,这表明页面已缓存,并且从浏览器的缓存中显示,而不是从服务器请求的页面。要修复它,你需要适当地设置HTTP响应头。这已在Making sure a web page is not cached, across all browsers中事先得到解答。只是重复BalusC,它们是:

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. 
response.setHeader("Pragma", "no-cache"); // HTTP 1.0. 
response.setDateHeader("Expires", 0); // Proxies. 

最合适的地方设置这些标题是网页过滤器,你似乎并不需要任何JSF财物那里。您可以在Avoid back button on JSF web application的答案中找到更多信息。要重复BalusC的代码,您将拥有:

@WebFilter("/secured/*") 
public class NoCacheFilter implements Filter { 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 

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

     chain.doFilter(req, res); 
    } 

    // ... 

} 

只要不要忘记告诉您需要过滤哪些页面。这样,所请求的新页面将始终从服务器发送,而不会再被缓存。因此,如果用户在注销发生后尝试访问受保护的页面(通过会话失效并发送重定向),则您的标准安全手段将会启动(其他过滤器),从而阻止用户访问这些页面。

接下来要做的事情是解释JSF如何在会话失效/超时时处理已打开的页面。换句话说,你如何处理ViewExpiredException s。对于同步POST请求,这又在How to handle session expiration and ViewExpiredException in JSF 2?javax.faces.application.ViewExpiredException: View could not be restored中进行了回答,对于AJAX请求在Session timeout and ViewExpiredException handling on JSF/PrimeFaces ajax request中进行了回答。

基本上,对于前者,你需要以下几行添加到你的web.xml:

<error-page> 
    <exception-type>javax.faces.application.ViewExpiredException</exception-type> 
    <location>/expired.xhtml</location> 
</error-page> 

对于后者,我热烈推荐你看看JSF工具库OmniFaces及其FullAjaxExceptionHAndler这是为此设计。

+0

非常感谢@skuntsel,但我仍然试图做的是,当用户点击该缓存页面命令按钮时,它应该将sessionsexpires页面(因为我无效的会话),但不会执行单击该按钮时的操作 –

0

即使服务器上的会话失效,浏览器也会将您带回数据页面,因为该页面缓存在浏览器内存中。

按照this关于浏览器的后退按钮如何工作。

您可以参考this来解决您的问题。

+0

谢谢@joe,但这不是我的问题,我知道页面缓存,因为我从[这里]了解到(http://stackoverflow.com/questions/5619827/how-to- invalidate-session-in-jsf-2-0)由BalusC,但如果我点击任何命令按钮,它应该带我到sessionexpire页面,但不是通过该按钮请求页面的页面。 –