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

时间:2022-05-27 20:03:44

In OmniFaces, the FullAjaxExceptionHandler, after having found the right error page to use, calls the JSF runtime to build the view and render it instead of the page that includes the AJAX call.

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

Why this? IMHO it would be simpler to just perform a ExternalContext#redirect()? Are there specific reasons to do this?

为什么呢?执行ExternalContext#redirect()会更简单?这样做有什么特别的原因吗?

We are writing our own ExceptionHandler based on FullAjaxExceptionHandler and wanted to understand the reason behind this design.

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

1 个解决方案

#1


5  

The primary goal of the FullAjaxExceptionHandler is to let exceptions during ajax requests to behave exactly the same as exceptions during non-ajax requests. The developer must be able to reuse the error pages across both conditions without worrying about the condition while implementing the error pages.

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

A redirect isn't part of the normal flow during non-ajax requests. The default <error-page> mechanism in web.xml performs a forward to display the error page, not a redirect. If a redirect was performed, all error page request attributes such as javax.servlet.error.exception would get lost and render as null. Moreover, normal practice is to place error pages in /WEB-INF to prevent endusers from being able to directly access (and bookmark and share) them. A redirect would require them to be publicly accessible, which indicates a major design problem (is the intented target page actually a real error page?).

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

If you really need to perform a redirect to/from your error page, either homegrow a custom exception handler which explicitly invokes ExternalContext#redirect() and doesn't utilize web.xml <error-page> mechanism, or add a <meta http-equiv="refresh" ...> to the HTML head of the error page in question (example here).

如果您确实需要执行到/从错误页面的重定向,可以使用自定义异常处理程序,该处理程序显式调用ExternalContext#redirect(),并且不使用web。xml 机制,或添加 到错误页面的HTML头部(这里的示例)。

In case you actually intended to redirect to some login page when a ViewExpiredException occurs, then you should realize that there's a big difference between the cases of "User is not logged in" and "Session/view is expired". For the former, you should not be catching ViewExpiredException at all, but use a simple servlet filter which checks if the user is logged in and redirect accordingly, long before the FacesServlet is invoked. A normal authentication framework (JAAS, Shiro, Spring Security, etc) also works that way.

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

See also:

#1


5  

The primary goal of the FullAjaxExceptionHandler is to let exceptions during ajax requests to behave exactly the same as exceptions during non-ajax requests. The developer must be able to reuse the error pages across both conditions without worrying about the condition while implementing the error pages.

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

A redirect isn't part of the normal flow during non-ajax requests. The default <error-page> mechanism in web.xml performs a forward to display the error page, not a redirect. If a redirect was performed, all error page request attributes such as javax.servlet.error.exception would get lost and render as null. Moreover, normal practice is to place error pages in /WEB-INF to prevent endusers from being able to directly access (and bookmark and share) them. A redirect would require them to be publicly accessible, which indicates a major design problem (is the intented target page actually a real error page?).

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

If you really need to perform a redirect to/from your error page, either homegrow a custom exception handler which explicitly invokes ExternalContext#redirect() and doesn't utilize web.xml <error-page> mechanism, or add a <meta http-equiv="refresh" ...> to the HTML head of the error page in question (example here).

如果您确实需要执行到/从错误页面的重定向,可以使用自定义异常处理程序,该处理程序显式调用ExternalContext#redirect(),并且不使用web。xml 机制,或添加 到错误页面的HTML头部(这里的示例)。

In case you actually intended to redirect to some login page when a ViewExpiredException occurs, then you should realize that there's a big difference between the cases of "User is not logged in" and "Session/view is expired". For the former, you should not be catching ViewExpiredException at all, but use a simple servlet filter which checks if the user is logged in and redirect accordingly, long before the FacesServlet is invoked. A normal authentication framework (JAAS, Shiro, Spring Security, etc) also works that way.

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

See also: