Suite à ma question précédente dans Creating FacesMessage in action method outside JSF conversion/validation mechanism?, j'essaie de gérer les exceptions levées à partir de la couche de gestion en dehors de mes beans gérés.JSF 2: Est-ce une bonne approche pour gérer les exceptions métier?
La stratégie consiste à rechercher et convertir des exceptions d'affaires aux messages de visages dans le PhaseListener.
Cela fonctionne comme je l'espérais, mais je me demandais juste si je ne faisais que réinventer la roue, ou le faire correctement avec le mauvais sens?
Voici mon exemple de code extrait:
public class BusinessExceptionHandler implements PhaseListener {
@Override
public void afterPhase(PhaseEvent phaseEvent) {
ExceptionHandler exceptionHandler = phaseEvent.getFacesContext().getExceptionHandler();
// just debugging the handled exception, nothing here
/*
for (ExceptionQueuedEvent event : exceptionHandler.getHandledExceptionQueuedEvents()) {
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
System.out.println("handled exception : " + context.getException());
}*/
for (Iterator<ExceptionQueuedEvent> it = exceptionHandler.getUnhandledExceptionQueuedEvents().iterator();
it.hasNext();) {
ExceptionQueuedEvent event = it.next();
ExceptionQueuedEventContext eventContext = (ExceptionQueuedEventContext) event.getSource();
Throwable e = eventContext.getException();
System.out.println("unhandled exception : " + e);
// get the root cause exception
while (e.getCause() != null) {
e = e.getCause();
}
System.out.println("cause exception : " + e +
", cause exception is BE : " + (e instanceof BusinessException));
// handle BE
if (e instanceof BusinessException) {
BusinessException be = (BusinessException) e;
System.out.println("processing BE " + be);
FacesMessage message = Messages.getMessage(
"com.corejsf.errors",
be.getMessage(),
be.getParamValues()
);
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, message);
it.remove(); // remove the exception
// works fine without this block, if BE is thrown, always return to the original page
/*
NavigationHandler navigationHandler = context.getApplication().getNavigationHandler();
System.out.println("navigating to " + context.getViewRoot().getViewId());
navigationHandler.handleNavigation(context, context.getViewRoot().getViewId(), null);
*/
}
}
}
@Override
public void beforePhase(PhaseEvent phaseEvent) {
}
@Override
public PhaseId getPhaseId() {
return PhaseId.INVOKE_APPLICATION;
}
}
Merci!
Cordialement, Albert Kam
Salut à nouveau. Merci pour l'idée. La page 282 n'est pas disponible. Mais après quelques recherches, j'ai trouvé l'article d'Edburn sur ce genre de sujet, et j'utiliserai cette pratique plus tard: http://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception- jsf2 – bertie