JSF 重定向在过滤器中导致异常

Posted

技术标签:

【中文标题】JSF 重定向在过滤器中导致异常【英文标题】:JSF Redirect causes exception in a filter 【发布时间】:2012-12-12 14:51:46 【问题描述】:

我已经为我想要保护的任何页面配置了一个身份验证过滤器。 但是,当它尝试重定向到登录页面时,我遇到了以下错误

com.sun.faces.context.FacesFileNotFoundException

..这是我的过滤器

@WebFilter(filterName = "Authentication Filter", urlPatterns =  "/pages/*" , dispatcherTypes = 
        DispatcherType.REQUEST, DispatcherType.FORWARD )
public class AuthenticationFilter implements Filter 
    static final Logger logger = Logger.getLogger(AuthenticationFilter.class);
    private String contextPath;

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException 
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        if (httpRequest.getUserPrincipal() == null) 
            httpResponse.sendRedirect(contextPath
                    + "/faces/pages/public/login.xhtml");
            return;
        
        chain.doFilter(request, response);
    
    public void init(FilterConfig fConfig) throws ServletException 
        contextPath = fConfig.getServletContext().getContextPath();
    

..我的 web.xml 被映射到 faces servlet 的这个代码

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

不确定,但我已验证该路径存在于我的项目文件夹中

+pages
    +public
        -login.xhtml

生成的路径是

http://localhost:8080/MyApp/faces/pages/public/login.xhtml

有人知道原因吗?

【问题讨论】:

【参考方案1】:

/faces 路径前缀通常默认添加到某些 IDE(即 NetBeans)的 faces url-pattern 中。您可能已经从 web.xml 更改了它,但您还没有从过滤器 sendRedirect 参数中删除 if。

为了使您的过滤器正常工作,请从过滤器中的 sendRedirect() 方法中删除 /faces 前缀:

httpResponse.sendRedirect(contextPath + "/pages/public/login.xhtml");

或像这样将其添加到 web.xml:

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>

最后,请注意您的过滤器不会导致无限循环。在重定向之前添加此检查可能很有用:

HttpServletRequest req = (HttpServletRequest) request;
if (!req.getRequestURI().contains("/pages/public/login.xhtml") && httpRequest.getUserPrincipal() == null) 
        // redirect
        return;
    

【讨论】:

【参考方案2】:

异常表明 JSF 无法定位视图。你的项目是否有这个目录结构:contextRoot/faces/pages/public/login.xhtml

【讨论】:

以上是关于JSF 重定向在过滤器中导致异常的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PrimeFaces 在 JSF 上重定向?

在 servlet 过滤器中使用请求参数将 JSF ajax 请求重定向到 URL

我的过滤器之前的 JSF 表单登录页面重定向命中

使用 JSF 2.0 实现重定向登录的正确方法是啥?

在过滤器中重定向时停止进一步处理

使用过滤器类的重定向过多