2012-05-10 9 views
22

Tutti gli ExceptionHandlerFactory esempi che ho incontrato finora reindirizzare un utente a una pagina viewExpired.jsf nel caso in cui un ViewExpiredException 'colto:Perché utilizzare JSF ExceptionHandlerFactory anziché il reindirizzamento <error-page>?

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(); 
    } 
} 

Mi sembra che la seguente configurazione semplice web.xml è fondamentalmente lo stesso e molto più semplice:

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

Sorge quindi la domanda - perché si potrebbe usare un ExceptionHandlerFactory?

+0

Il codice sopra è il tuo? se no, puoi accreditare la fonte? – Mindwin

risposta

23

L'esempio particolare si fa solo una cosa utile: salva l'ID vista come un attributo richiesta in modo che è possibile utilizzare per esempio

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

ma questo non è estremamente utile come la richiesta grezzo URI è già disponibile dall'attributo di richiesta predefinito <error-page>javax.servlet.error.request_uri.

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

Tuttavia una cosa quello che un costume ExceptionHandler è veramente utile per è che permette di trattare con le eccezioni durante ajax richieste. Di default non hanno una singola forma di feedback utile sul lato client. Solo a Mojarra con la fase del progetto impostata su "Sviluppo" vedrai un messaggio di avviso JavaScript con il messaggio di eccezione. Ma è così. Non c'è una singola forma di feedback nella fase di "Produzione". Con una personalizzata ExceptionHandler, è possibile analizzare lo web.xml per trovare le posizioni della pagina di errore, creare un nuovo UIViewRoot con esso e forzare JSF a impostare il rendering ajax su @all.

Quindi, fondamentalmente :

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

Vedi anche questa domanda correlata: What is the correct way to deal with JSF 2.0 exceptions for AJAXified components? e questo blog: Full Ajax Exception Handler.

+0

È possibile utilizzare OmniFaces 'org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory' insieme alla gestione delle eccezioni creando un' ExceptionHandlerFactory' in questo modo per deviare a una pagina di errore globale, quando le eccezioni sono gettato che non devono essere avvolti da questa fabbrica? La documentazione richiede solo un factory di gestione delle eccezioni per applicazione, "* Ci deve essere un'istanza di' ExceptionHandlerFactory' per ogni applicazione Web che utilizza JavaServer Faces. Questa istanza può essere acquisita, in modo portatile, chiamando. * "Funziona bene l'inoltro a proposito di una pagina di errore globale. – Tiny

+0

@Tiny: puoi estenderlo. Vedi anche javadoc. Sovrascrivi 'shouldHandleExceptionRootCause()' per restituire 'false' (e aggiungere quel messaggio fatale). – BalusC

3

Dipende da cosa si vuole fare quando si riceve ViewExpiredException.

Se si desidera visualizzare solo una pagina di errore utente, è possibile farlo come si è detto.

Questo post mostrano come a livello di codice intercetta il ViewExpiredException e fare qualcosa di bello con esso.

+1

collegamento è rotto, aggiungere un collegamento funzionante, – aName

Problemi correlati