当用户单击浏览器的后退按钮时您会看到以前的页面这一事实表明这些页面已被缓存并且是从浏览器的缓存中显示的,而不是从服务器请求的。要修复它,您需要适当地设置 HTTP 响应标头。这已在确保网页未在所有浏览器中缓存中预先得到解答。只是重复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.
设置这些标头的最合适的位置是 Web 过滤器,因为在那里您似乎不需要任何 JSF 物品。您可以在“避免 JSF Web 应用程序上的后退按钮”的答案中找到更多信息。要重复 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。这又在如何处理 JSF 2 中的会话过期和 ViewExpiredException 中得到回答?和javax.faces.application.ViewExpiredException: View could not be restore for 同步 POST 请求以及AJAX 请求的JSF/PrimeFaces ajax 请求的会话超时和 ViewExpiredException 处理。
基本上,对于前者,您需要将以下行添加到您的 web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/expired.xhtml</location>
</error-page>
对于后者,我强烈建议您查看 JSF 实用程序库OmniFaces及其专为此目的而设计的FullAjaxExceptionHAndler 。