使用登录过滤器时缺少JSF页面样式

时间:2013-01-25 16:54:57

标签: jsf

我正在使用以下过滤器来控制使用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);
    }
}

1 个答案:

答案 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 /图像文件上浏览器缓存的优势。