2012-05-10 16 views
22

Todas las ExceptionHandlerFactory ejemplos que he encontrado hasta ahora redirigir a los usuarios a una página viewExpired.jsf en el caso de que un ViewExpiredException estaba en:¿Por qué usar un JSF ExceptionHandlerFactory en lugar de la redirección <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(); 
    } 
} 

Me parece que la siguiente configuración simple web.xml es fundamentalmente el mismo y mucho más simple:

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

Esto lleva a la pregunta - ¿por qué uno utilizar un ExceptionHandlerFactory?

+0

¿El código que está arriba es el suyo? si no, ¿puedes acreditar la fuente? – Mindwin

Respuesta

23

El ejemplo particular no sólo una cosa útil: guarda el ID de vista como un atributo pedido, por lo que se puede utilizar, por ejemplo,

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

pero esto no es tremendamente útil como la solicitud de prima URI ya está disponible mediante el atributo de solicitud predeterminada <error-page>javax.servlet.error.request_uri.

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

Sin embargo una cosa lo que una costumbre ExceptionHandler es realmente útil para es que permite que usted pueda manejar excepciones durante peticiones Ajax. Por defecto, no tienen ninguna forma única de comentarios útiles en el lado del cliente. Solo en Mojarra, con la etapa del proyecto configurada en "Desarrollo", verá un mensaje de alerta de JavaScript con el mensaje de excepción. Pero eso es todo. No hay una forma única de retroalimentación en la etapa de "Producción". Con un ExceptionHandler personalizado, podrá analizar el web.xml para encontrar las ubicaciones de la página de error, crear un nuevo UIViewRoot con él y forzar a JSF a establecer la representación de ajax en @all.

Así que, básicamente :

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

Ver también esta pregunta relacionada: What is the correct way to deal with JSF 2.0 exceptions for AJAXified components? y este blog: Full Ajax Exception Handler.

+0

Se puede utilizar OmniFaces 'org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory' junto con el manejo de excepciones creando un' ExceptionHandlerFactory' de esta manera para desviar a páginas de error globales, cuando las excepciones son arrojado que no deben ser envueltos por esta fábrica? La documentación requiere solo una fábrica de manejador de excepciones por aplicación, "* Debe haber una instancia' ExceptionHandlerFactory' por aplicación web que utiliza JavaServer Faces. Esta instancia se puede adquirir, de forma portátil, llamando. * "Esto funciona bien reenviar a una página de error global, por cierto. – Tiny

+0

@Tiny: puede extenderlo. Ver también javadoc. Reemplazar 'shouldHandleExceptionRootCause()' para devolver 'false' (y agregar ese mensaje fatal). – BalusC

3

Depende de qué desea hacer cuando recibe ViewExpiredException.

Si solo desea mostrar una página de error de usuario puede hacerlo como usted dijo.

Este post le muestra cómo interceptar mediante programación el ViewExpiredException y hacer algo bueno con él.

+1

el enlace está roto, por favor agregue un enlace de trabajo, – aName

Cuestiones relacionadas