为什么FullAjaxExceptionHandler不是简单地执行ExternalContext#redirect()?

时间:2014-10-27 13:36:23

标签: ajax jsf redirect omnifaces exceptionhandler

在OmniFaces中,FullAjaxExceptionHandler在找到正确的错误页面后,调用JSF运行时来构建视图并呈现它而不是包含AJAX调用的页面。

为什么这样?恕我直言,只执行ExternalContext#redirect()会更简单吗?有没有具体的理由这样做?

我们正在编写基于FullAjaxExceptionHandler的我们自己的ExceptionHandler,并希望了解这种设计背后的原因。

1 个答案:

答案 0 :(得分:5)

FullAjaxExceptionHandler的主要目标是让ajax请求中的异常与非ajax请求中的异常行为完全相同。开发人员必须能够在两种条件下重用错误页面,而不必担心在实现错误页面时的情况。

在非ajax请求期间,重定向不是正常流的一部分。 <error-page>中的默认web.xml机制执行转发以显示错误页面,而不是重定向。如果执行了重定向,则javax.servlet.error.exception等所有错误页面请求属性都将丢失并呈现为null。此外,通常的做法是在/WEB-INF中放置错误页面,以防止最终用户能够直接访问(以及书签和共享)它们。重定向将要求它们可公开访问,这表明存在一个主要的设计问题(目标页面实际上是真正的错误页面吗?)。

如果您确实需要在错误页面中执行重定向,请自行生成自定义异常处理程序,该处理程序明确调用ExternalContext#redirect()并且不使用web.xml <error-page>机制,或者将<meta http-equiv="refresh" ...>添加到相关错误页面的HTML头部(example here)。

如果您确实想在ViewExpiredException发生时重定向到某个登录页面,那么您应该意识到“用户未登录”和“会话/视图已过期”的情况之间存在很大差异”。对于前者,您根本不应该捕获ViewExpiredException,而是使用简单的servlet filter来检查用户是否已登录并相应地重定向,早在调用FacesServlet之前。普通的身份验证框架(JAAS,Shiro,Spring Security等)也可以这样工作。

另见: