在 ViewHandler#createView() 中区分 <error-page> 视图和普通视图

Distinguish <error-page> view from normal view in ViewHandler#createView()

我在我的 web.xml 中为错误 404 定义了这样的错误页面:

<error-page>
    <error-code>404</error-code>
    <location>/common/messages/pageNotFoundError.jsf</location>
</error-page>

处理无效页面 url 按预期工作 - 用户被重定向到 pageNotFoundError 页面。

我还在 faces-config.xml 中定义了自定义视图处理程序。视图处理程序覆盖方法 createView(FacesContext context, String viewId).

现在是问题所在 - 当页面包含带有无效路径的图形图像时(我无法避免,因为用户可以自己定义路径),createView 方法被调用两次。一次使用 viewId = 当前页面 ID(如我所料),一次使用 viewId =“/common/messages/pageNotFoundError.jsf”。有什么方法可以区分 createView 方法 "normal" 页面创建与 404(或任何其他)错误处理(我不想比较 viewId 字符串)?或者在这种情况下不应该调用 createView 方法 - 在这种情况下,我的问题是如何更改配置以实现此目的?

当servlet容器调度到错误页面时,它会在当前HTTP servlet请求中设置一堆特殊的错误页面相关属性。这些键由 RequestDispatcher class. Among others, the original request URI for which the error page is being dispatched is available by ERROR_REQUEST_URI 键中的那些 ERROR_XXX 常量字段值标识。如果这不是 null,那么您知道正在分派错误页面,并且您立即获得了原始请求 URI。

换句话说,

ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
String originalURI = (String) ec.getRequestMap().get(RequestDispatcher.ERROR_REQUEST_URI);

if (originalURI != null) {
    // An error page was dispatched for the given original URI.
} else {
    // We're most likely in the normal flow.
}