2012-05-10 4 views
22

Alle der ExceptionHandlerFactory Beispiele, die ich über gekommen sind bisher einen Benutzer zu einer viewExpired.jsf Seite im Falle umleiten, dass ein ViewExpiredException gefangen wird:Warum eine JSF ExceptionHandlerFactory anstelle von <error-page> Umleitung verwenden?

public class ViewExpiredExceptionExceptionHandler extends ExceptionHandlerWrapper { 
    private ExceptionHandler wrapped; 

    public ViewExpiredExceptionExceptionHandler(ExceptionHandler wrapped) { 
     this.wrapped = wrapped; 
    } 

    @Override 
    public ExceptionHandler getWrapped() { 
     return this.wrapped; 
    } 

    @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; 
       FacesContext facesContext = FacesContext.getCurrentInstance(); 
       Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap(); 
       NavigationHandler navigationHandler = facesContext.getApplication().getNavigationHandler(); 
       try { 
        // Push some useful stuff to the request scope for use in the page 
        requestMap.put("currentViewId", vee.getViewId()); 
        navigationHandler.handleNavigation(facesContext, null, "/viewExpired"); 
        facesContext.renderResponse(); 
       } finally { 
        i.remove(); 
       } 
      } 
     } 

     // At this point, the queue will not contain any ViewExpiredEvents. Therefore, let the parent handle them. 
     getWrapped().handle(); 
    } 
} 

Es scheint mir, dass die folgenden einfachen web.xml Konfiguration grundsätzlich die gleiche ist und viel einfacher:

<error-page> 
    <exception-type>javax.faces.application.ViewExpiredException</exception-type> 
    <location>/viewExpired.jsf</location> 
</error-page> 

sich die Frage aufgefordert - warum sollte man eine ExceptionHandlerFactory benutzen?

+0

Ist der Code über Ihrem? Wenn nicht, können Sie die Quelle gutschreiben? – Mindwin

Antwort

23

Das spezielle Beispiel nicht nur eine nützliche Sache: es die Ansicht ID als Anforderung Attribut speichert, so dass Sie zum Beispiel

<h:link value="Go back to previous page" outcome="#{currentViewId}" /> 

Aber das ist nicht enorm nützlich als Ausgangs Anfrage nutzen können URI ist bereits verfügbar durch das Standardanforderungsattribut der <error-page>javax.servlet.error.request_uri.

<h:outputLink value="#{requestScope['javax.servlet.error.request_uri']}">Go back to previous page</h:outputLink> 

jedoch eine Sache, was eine individuelle ExceptionHandler für wirklich nützlich ist, ist, dass es Ihnen mit Ausnahmen bei Ajax fordert umgehen können. Standardmäßig haben sie nämlich keine einzige Form von hilfreichem Feedback auf der Client-Seite. Nur in Mojarra mit der Projektstufe "Entwicklung" sehen Sie eine leere JavaScript-Warnmeldung mit der Ausnahmebedingungsnachricht. Aber das ist es. Es gibt keine einzige Form der Rückmeldung in der Phase "Produktion". Mit einer benutzerdefinierten ExceptionHandler könnten Sie die web.xml analysieren, um die Fehler Seitenpositionen zu finden, erstellen Sie eine neue UIViewRoot mit ihm und zwingen JSF, AJAX-Rendering auf @all zu setzen.

So grundsätzlich:

String errorPageLocation = "/WEB-INF/errorpages/500.xhtml"; 
context.setViewRoot(context.getApplication().getViewHandler().createView(context, errorPageLocation)); 
context.getPartialViewContext().setRenderAll(true); 
context.renderResponse(); 

Siehe auch diese Frage im Zusammenhang: What is the correct way to deal with JSF 2.0 exceptions for AJAXified components? und dieser Blog: Full Ajax Exception Handler.

+0

Kann OmniFaces 'org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory' zusammen mit der Behandlung von Ausnahmen verwendet werden, indem eine' ExceptionHandlerFactory' erstellt wird, um auf globale Fehlerseiten umzuleiten, wenn Ausnahmen vorhanden sind geworfen, die von dieser Fabrik nicht eingewickelt werden sollen? Die Dokumentation erfordert nur eine Ausnahmebehandlungsfactory pro Anwendung: "Es muss eine' ExceptionHandlerFactory' -Instanz pro Webanwendung geben, die JavaServer Faces verwendet. Diese Instanz kann auf tragbare Weise durch Aufrufen erworben werden. * "Dies funktioniert gut zu einer globalen Fehlerseite, nebenbei bemerkt. – Tiny

+0

@ Tiny: Sie können es erweitern. Siehe auch javadoc. Überschreiben Sie 'sollteHandleExceptionRootCause()', um 'false' zurückzugeben (und fügen Sie diese fatale Nachricht hinzu). – BalusC

3

Es hängt davon ab, was Sie tun möchten, wenn Sie ViewExpiredException erhalten.

Wenn Sie nur zu einer Benutzerfehlerseite anzeigen möchten, können Sie es tun, wie Sie sagten.

Diese post zeigen Ihnen, wie Sie die ViewExpiredException programmatisch abfangen und etwas nettes damit tun.

+1

Link ist kaputt, bitte fügen Sie einen funktionierenden Link hinzu, – aName

Verwandte Themen