在 OmniFaces 中,FullAjaxExceptionHandler在找到要使用的正确错误页面后,调用 JSF 运行时来构建视图并呈现它,而不是包含 AJAX 调用的页面。
为什么这个?恕我直言,只执行一个会更简单ExternalContext#redirect()
吗?有具体的理由这样做吗?
我们正在编写自己的基于 FullAjaxExceptionHandler 的 ExceptionHandler,并想了解这种设计背后的原因。
在 OmniFaces 中,FullAjaxExceptionHandler在找到要使用的正确错误页面后,调用 JSF 运行时来构建视图并呈现它,而不是包含 AJAX 调用的页面。
为什么这个?恕我直言,只执行一个会更简单ExternalContext#redirect()
吗?有具体的理由这样做吗?
我们正在编写自己的基于 FullAjaxExceptionHandler 的 ExceptionHandler,并想了解这种设计背后的原因。
的主要目标FullAjaxExceptionHandler
是让 ajax 请求期间的异常行为与非 ajax 请求期间的异常完全相同。开发人员必须能够在两种情况下重用错误页面,而不用担心在实现错误页面时的情况。
在非 ajax 请求期间,重定向不是正常流程的一部分。中的默认<error-page>
机制web.xml
执行转发以显示错误页面,而不是重定向。如果执行了重定向,则所有错误页面请求属性,例如javax.servlet.error.exception
将丢失并呈现为null
. 此外,通常的做法是放置错误页面,/WEB-INF
以防止最终用户能够直接访问(以及添加书签和共享)它们。重定向将要求它们可公开访问,这表明存在主要设计问题(意图的目标页面实际上是真正的错误页面吗?)。
如果您确实需要执行到/从错误页面的重定向,请自行开发一个自定义异常处理程序,该处理程序显式调用ExternalContext#redirect()
且不使用web.xml
<error-page>
机制,或者将 a 添加<meta http-equiv="refresh" ...>
到相关错误页面的 HTML 头部(此处示例)。
如果您实际上打算在发生 aViewExpiredException
时重定向到某个登录页面,那么您应该意识到“用户未登录”和“会话/视图已过期”的情况之间存在很大差异。对于前者,您根本不应该捕获ViewExpiredException
,而是使用一个简单的servlet 过滤器来检查用户是否已登录并相应地重定向,早在FacesServlet
调用之前。普通的身份验证框架(JAAS、Shiro、Spring Security 等)也可以这样工作。