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