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中默认的
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
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:
- What is the good approach to forward the exception from servlets to a jsp page?
- 将异常从servlet转发到jsp页面的好方法是什么?
- What is the difference between redirect and navigation/forward and when to use what?
- 重定向和导航/向前以及何时使用什么有什么区别?
- Why use a JSF ExceptionHandlerFactory instead of <error-page> redirection?
-
为什么要使用JSF ExceptionHandlerFactory而不是
重定向? - Check if session exists JSF
- 检查会话是否存在JSF
- Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same
- 会话到期时的授权重定向不能用于提交JSF表单,页面保持不变
#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中默认的
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
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:
- What is the good approach to forward the exception from servlets to a jsp page?
- 将异常从servlet转发到jsp页面的好方法是什么?
- What is the difference between redirect and navigation/forward and when to use what?
- 重定向和导航/向前以及何时使用什么有什么区别?
- Why use a JSF ExceptionHandlerFactory instead of <error-page> redirection?
-
为什么要使用JSF ExceptionHandlerFactory而不是
重定向? - Check if session exists JSF
- 检查会话是否存在JSF
- Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same
- 会话到期时的授权重定向不能用于提交JSF表单,页面保持不变