![]() |
![]() |
![]() |
![]() |
|
Exception Handling
Kennen sie die Situation, wenn sie auf eine Webseite gehen und dort
plötzlich ein StackTrace zu sehen ist? Das wirkt professionell, nicht wahr?
Natürlich ist dies der Worst Case, wenn dem Anwender im Fehlerfalle ein
Stacktrace angezeigt wird. So etwas darf nicht passieren. Aber wie kann man
dies verhindern? Man könnte sicherlich eine globale Fehlerseite in der web.xml
angeben, die zumindest die Anzeige eines StackTraces verhindert. Aber vielleicht
möchten sie mehr tun: die Betriebsüberwachung benachrichtigen, Loggen, und
dem Anwender eine sinnvolle Meldung anzeigen ("Bitte versuchen sie es zu einem
späteren Zeitpunkt noch einmal." ;-) ).
<h:commandButton value="Make Error" action="#{simpleController.doSomethingSilly}" />
Hier ist zunächst ein trivialer CommandButton zu sehen. Mein erzwungener Fehler passiert in der Aktionsmethode. @ManagedBean
Wenn dieser Code ausgeführt wird, erscheint eine Fehlerseite inklusive einem Stacktrace. Für
unser Beispiel möchte ich es jetzt wie folgt behandeln: Es soll einfach auf die Startseite
weiternavigiert werden und dem Benutzer eine Meldung angezeigt werden.
public class SimpleController { public String doSomethingSilly() { String s = null; // Aua ! s.length(); return null; } } Um dies zu realisieren, muss zunächst eine ExceptionHandler-Factory in JSF bekanntgemacht werden. <factory>
<exception-handler-factory>de.jsfforum.training.ui.error.MyExceptionHandlerFactory</exception-handler-factory> </factory> Nach dem bekannten JSF Decorator Pattern (Verhalten wird nicht ersetzt, sondern ergänzt), kommt eine neue Factory dazu. package de.jsfforum.training.ui.error;
Die Factory ist recht unspektakulär, wird lediglich ein eigener ExceptionHandler erzeugt.
Der Handler ist nun das Herzstück der ganzen Angelegenheit:
import javax.faces.context.ExceptionHandler; import javax.faces.context.ExceptionHandlerFactory; public class MyExceptionHandlerFactory extends ExceptionHandlerFactory { private ExceptionHandlerFactory parent; public MyExceptionHandlerFactory( ExceptionHandlerFactory parent ) { this.parent = parent; } @Override public ExceptionHandler getExceptionHandler() { ExceptionHandler result = parent.getExceptionHandler(); result = new MyExceptionHandler(result); return result; } } package de.jsfforum.training.ui.error;
import java.util.Iterator; import javax.faces.FacesException; import javax.faces.application.FacesMessage; import javax.faces.application.NavigationHandler; import javax.faces.context.ExceptionHandler; import javax.faces.context.ExceptionHandlerWrapper; import javax.faces.context.FacesContext; import javax.faces.event.ExceptionQueuedEvent; import javax.faces.event.ExceptionQueuedEventContext; public class MyExceptionHandler extends ExceptionHandlerWrapper { private ExceptionHandler wrapped; public MyExceptionHandler(ExceptionHandler wrapped) { this.wrapped = wrapped; } @Override public ExceptionHandler getWrapped() { return this.wrapped; } @Override public void handle() throws FacesException { Iterator<ExceptionQueuedEvent> itr = getUnhandledExceptionQueuedEvents().iterator(); while ( itr.hasNext() ) { ExceptionQueuedEvent event = itr.next(); ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource(); Throwable thr = context.getException(); if ( thr instanceof FacesException ) { FacesContext fc = FacesContext.getCurrentInstance(); NavigationHandler nav = fc.getApplication().getNavigationHandler(); try { fc.addMessage( null, new FacesMessage("Lieber Anwender, leider ist bei uns etwas schief gegangen. :-") ); nav.handleNavigation(fc, null, "startseite" ); fc.renderResponse(); } finally { itr.remove(); } } } getWrapped().handle(); } } Es werden zunächst alle Exceptions betrachtet, die in der Queue hängen. Wenn ein "passender" dabei ist, wird eine neue Message erzeugt und auf die Startseite verwiesen. An dieser Stelle könnte natürlich eine beliebige projektspezifische Fehlerverarbeitung erfolgen. Fazit: Mit einem eigenen Exception Handler hat es der Entwickler zukünftig selber in der Hand, vernünftig auf Exceptions zu reagieren. Zurück zur Übersichtsseite |
|||||||||||