问题
I've read the question Handle ViewExireException/ajax and display a Primefaces dialog and the answer from BalusC. I'd want to handle the ViewExpiredException
by showing the alert with information to refresh the page. I've taken the suggestion from BalusC to user RequestContext
to put JavaScript to execute, and I've removed the JSF redirection because I'm not using it:
@Override
public void handle() throws FacesException {
for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
Throwable t = context.getException();
if (t instanceof ViewExpiredException) {
ViewExpiredException vee = (ViewExpiredException) t;
try {
log.info("Catched ViewExpiredException for view {}", vee.getViewId());
RequestContext.getCurrentInstance().execute("handleViewExpired("+vee.getViewId()+")");
return;
} finally {
i.remove();
}
}
}
// At this point, the queue will not contain any ViewExpiredEvents.
// Therefore, let the parent handle them.
getWrapped().handle();
}
The problem is, I got NullPointerException
when executing the handle method from wrapped
handler. I've added the return clause, and after adding it, the effect was the same:
[30.01.13 15:45:59:140 CET] 0000002e ErrorPageWrit E An exception occurred javax.faces.FacesException: java.lang.NullPointerException at org.apache.myfaces.shared_impl.context.ExceptionHandlerImpl.wrap(ExceptionHandlerImpl.java:241) at org.apache.myfaces.shared_impl.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:156) at my.project.web.handler.ViewExpiredExceptionExceptionHandler.handle(ViewExpiredExceptionExceptionHandler.java:59) at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:191) at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
So, the parent handle method is executed, thought there should be the return from method (The info string is logged).
I'm using PrimeFaces 3.4 and MyFaces 2.0.7, everything on WebSphere 7.
I don't understand what is happening here. Is it possible to achieve what I want, and if so, what I'm doing wrong?
回答1:
The best way was to handle that exception on client side. It's very simple few-liner and it's completly transparent:
var originalPrimeFacesAjaxResponseFunction = PrimeFaces.ajax.AjaxResponse;
PrimeFaces.ajax.AjaxResponse = function(data, status, xhr) {
var errorName = $(data.documentElement).find("error-name").text();
if (errorName == 'javax.faces.application.ViewExpiredException') {
alert('View has expired, redirection will follow');
window.location.reload();
} else {
originalPrimeFacesAjaxResponseFunction.apply(this, arguments);
}
};
No 2 new classes on server, no faces-config.xml
changes, this is what I love in programming.
来源:https://stackoverflow.com/questions/14606828/how-to-handle-viewexpiredexception-by-showing-javascript-alert