我正在使用以下过滤器来控制使用GlassFish作为应用程序服务器访问JSF 2.0中的所有页面。问题是,使用此代码虽然过滤器工作正常,如果用户尝试直接访问任何其他页面,但用户将重定向到log.xhtml但是login.xhtml看起来不太好(没有显示彩色图像,而页面形状发生变化),因为它应该是。但是,如果我删除sendRedirect语句并将其替换为chain.doFilter语句,那么页面显示方式应该看起来不错,但是过滤效果不明显。我该如何解决这个问题?
LoggingFilter.java
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) request;
LoginBean auth = (LoginBean) req.getSession().getAttribute("loginBean");
if ((auth != null && auth.isLoggedIn()) || req.getRequestURI().endsWith("/login.xhtml")) {
// User is logged in, so just continue request.
HttpServletResponse httpResponse = (HttpServletResponse)response;
httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0.
httpResponse.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(request, response);
} else {
// User is not logged in, so redirect to index.
HttpServletResponse res = (HttpServletResponse) response;
res.sendRedirect(req.getContextPath() + "/faces/login.xhtml");
//FacesContext.getCurrentInstance().getExternalContext().dispatch("/login.xhtml");
//chain.doFilter(request, response);
}
}
答案 0 :(得分:8)
此过滤器还会将CSS / JS /图像文件上的所有请求重定向到登录页面。浏览器最终得到一个响应,其中包含一些表示登录页面的HTML代码,而不是它请求的具体CSS / JS /图像内容,因此浏览器无法应用必要的look'n'feel。
如果您100%使用JSF资源管理(<h:outputStylesheet>
等),因此它们都被/javax.faces.resource/*
URI覆盖,请按如下方式重写您的过滤器:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
LoginBean auth = (session != null) ? session.getAttribute("loginBean") : null;
String loginURL = request.getContextPath() + "/faces/login.xhtml";
boolean loggedIn = auth != null && auth.isLoggedIn();
boolean loginRequest = request.getRequestURI().equals(loginURL);
boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + "/faces" + ResourceHandler.RESOURCE_IDENTIFIER);
if (loggedIn || loginRequest || resourceRequest)) {
if (!resourceRequest) {
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(request, response);
} else {
response.sendRedirect(loginURL);
}
}
请注意,不应在资源请求上设置no-cache标头,否则会破坏CSS / JS /图像文件上浏览器缓存的优势。