问题
I am trying to create a filter to handle exceptions (see Handling Uncaught Exception in JSF)
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
log.info("check filter is running");
chain.doFilter(request, response);
} catch (Exception e) {
log.error("Uncaught exception",e);
request.setAttribute("exception", e);
request.getRequestDispatcher("/error.xhtml").forward(request, response);
}
}
I execute the following method:
<p:commandButton value="Dispatch Order" update="@form"
action="#{orderBean.dispatchOrder()}">
</p:commandButton>
However, no exception is handled.
I see the error in the logs:
May 21, 2013 6:04:32 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: #{orderBean.dispatchOrder()}: MyException.....
What am I doing wrong?
回答1:
That old question was targeted on JSF 1.x and the answer is not applicable when you send a JSF 2.x ajax request. Your filter will only be invoked when you add ajax="false"
to the <p:commandButton>
or use the standard JSF <h:commandButton>
without <f:ajax>
. In order to handle exceptions on ajax requests, you need a custom ExceptionHandler.
See also:
- What is the correct way to deal with JSF 2.0 exceptions for AJAXified components?
回答2:
It's not best practice in JSF 2.0. Rather, see this: http://javalabor.blogspot.se/2011/09/jsf-2-global-exception-handling.html
Now as you may follow in the comments some people behind Solder / Seam 3 recommends Seam Catch instead. Seam Catch actually uses the same principles but in a much more refined way. Of course this is the CDI way to do things and considering the pre deprecation warning for JSF2 Beans you should be doing CDI imo.
Seam Catch have been ported to Deltaspike Core already but the JSF integration didn't make the cut for 0.4 so you will have to implement that yourself and then you can replace your implementation once it's implemented in deltaspike. Jira here: https://issues.apache.org/jira/browse/DELTASPIKE-341
This source code from Seam Catch will take you very far https://gist.github.com/mojavelinux/734963. But you should get a hold of the BeanManager like this instead:
BeanManager beanManager = BeanManagerProvider.getInstance()
.getBeanManager();
beanManager.fireEvent(catchEvent);
Here's the summary of what you need to do:
- Go CDI
- Add Deltaspike Core to the classpath
- Implement the your own ExceptionHandler etc accordingly to the source code from Seam with the adaptation I posted.
- Profit!!! Now you can use Exception Control from Deltaspike to catch your uncaught exceptions in a very smooth way. Please see here for details on how you implement the catching: http://incubator.apache.org/deltaspike/core.html#exception-control
Edit: The suggestion from BalusC is a good light weight candidate and it also comes in this flavor: http://fractalsoft.net/primeext-showcase-mojarra/views/ajaxErrorHandler.jsf
来源:https://stackoverflow.com/questions/16675663/uncaught-exception-handling-in-jsf