You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PrimeExceptionHandler时WEB-INF下错误页面找不到问题排查

核心原因
  • Servlet规范明确规定,WEB-INF目录下的所有资源禁止客户端直接访问,所有指向/WEB-INF/*路径的客户端请求都会被容器直接拦截返回404,只有服务器端的内部转发、包含操作才能访问这个目录下的内容。
  • 你配置的错误页路径指向WEB-INF下的xhtml文件时出现404,本质是当前异常处理流程没有走服务器内部转发,而是触发了客户端302重定向,让浏览器直接请求了WEB-INF下的地址,触发了容器的安全拦截。
  • 之所以会触发不该有的重定向,绝大多数情况是你没有给*.xhtml后缀绑定Faces Servlet映射。容器默认会对静态资源类型的错误页直接做内部转发,但如果目标错误页是需要经过动态Servlet解析的资源(比如JSF页面),又没有匹配到对应的Servlet处理逻辑,容器就会错误地走重定向逻辑,最终把WEB-INF的路径暴露给客户端。
  • 你把错误页移到webapp根目录能正常运行,是因为根目录下的资源没有访问限制,就算触发重定向,浏览器请求/expired.xhtml时不会被容器拦截,同时如果这个路径匹配了Faces Servlet的映射,就能正常渲染出页面。
修复步骤

按以下顺序调整配置即可让WEB-INF下的错误页正常生效:

  1. 先确认web.xml中Faces Servlet的映射规则覆盖所有xhtml文件,保证内部转发到xhtml页面时能被JSF引擎正常解析,参考配置如下:
<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>
  1. 确认错误页的配置路径写的是绝对上下文路径,也就是你最开始写的/WEB-INF/errorpages/expired.xhtml格式,开头的斜杠不能丢。
  2. 如果调整完上述配置还是出现跳转到WEB-INF路径报404的问题,可以加一个自定义异常过滤器,在过滤器里捕获ViewExpiredException,手动执行服务器内部转发到错误页,完全绕开容器默认的错误处理逻辑,核心逻辑参考:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    try {
        chain.doFilter(req, res);
    } catch (Exception e) {
        Throwable rootCause = getRootCause(e);
        if (rootCause instanceof ViewExpiredException) {
            req.getRequestDispatcher("/WEB-INF/errorpages/expired.xhtml").forward(req, res);
            return;
        }
        throw e;
    }
}
  1. 额外注意:WEB-INF下的错误页里引用的CSS、JS、图片等静态资源不要写相对路径,要放在webapp根目录的静态资源文件夹下用绝对路径引用,不然转发后会出现资源加载失败的问题。

内容的提问来源于stack exchange,提问作者grigouille

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 14:30:41