问题
How do I handle the exception and access the stack trace when an exception is thrown while processing a JSF ajax request? Right now, I only get the exception class name and message in a JavaScript alert when JSF project stage is set to Development. Even worse, there's no visual feedback whatsoever when JSF project stage is set to Production, and the server log doesn't show any information about the exception.
If that's relevant, I'm using GlassFish in Netbeans.
回答1:
This problem is known and fleshed out in among others the OmniFaces FullAjaxExceptionHandler showcase.
Basically, you need to create a custom ExceptionHandler as standard JSF doesn't provide one out the box (at least, not a sensible one). Therein you will be able to get hands on the Exception
instance causing all the trouble.
Here's a kickoff example:
public class YourExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
public YourExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public void handle() throws FacesException {
FacesContext facesContext = FacesContext.getCurrentInstance();
for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) {
Throwable exception = iter.next().getContext().getException(); // There it is!
// Now do your thing with it. This example implementation merely prints the stack trace.
exception.printStackTrace();
// You could redirect to an error page (bad practice).
// Or you could render a full error page (as OmniFaces does).
// Or you could show a FATAL faces message.
// Or you could trigger an oncomplete script.
// etc..
}
getWrapped().handle();
}
@Override
public ExceptionHandler getWrapped() {
return wrapped;
}
}
In order to get it to run, create a custom ExceptionHandlerFactory as follows:
public class YourExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public YourExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
return new YourExceptionHandler(parent.getExceptionHandler());
}
}
Which needs to be registered in faces-config.xml
as follows:
<factory>
<exception-handler-factory>com.example.YourExceptionHandlerFactory</exception-handler-factory>
</factory>
See also:
- Why FullAjaxExceptionHandler does not simply perform an ExternalContext#redirect()?
- Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same
来源:https://stackoverflow.com/questions/27526753/exception-handling-in-jsf-ajax-requests