2012-05-10 10 views
22

Wszystkie ExceptionHandlerFactory przykładów mam natknąć dotychczas przekierować użytkownika do viewExpired.jsf strony w przypadku gdy ViewExpiredException złowione:Dlaczego warto używać przekierowania JSF ExceptionHandlerFactory zamiast <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(); 
    } 
} 

Wydaje mi się, że po prosty web.xml konfiguracja jest zasadniczo taka sama i dużo prostsze:

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

Zmusza to pytanie - dlaczego by posłużyć się ExceptionHandlerFactory?

+0

Czy kod jest powyżej? jeśli nie, czy możesz podać źródło? – Mindwin

Odpowiedz

23

Szczególnym przykładem jest tylko jedna przydatna rzecz: to zapisuje identyfikator widoku za pomocą atrybutu żądanie, dzięki czemu można używać na przykład

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

Ale to nie jest ogromnie przydatny jako surowego żądanie URI jest już dostępny przez domyślny atrybut żądania <error-page>javax.servlet.error.request_uri.

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

Jednak jedna rzecz, co zwyczaj ExceptionHandler jest naprawdę przydatna jest to, że pozwala radzić sobie z wyjątkami podczas żąda AJAX. Domyślnie nie mają one żadnej formy przydatnej informacji zwrotnej po stronie klienta. Tylko w Mojarra ze sceną projektu ustawioną na "Rozwój" zobaczysz komunikat alertu JavaScript z komunikatem wyjątku. Ale to jest to. Nie ma jednej formy informacji zwrotnej na etapie "Produkcji". Z niestandardowym ExceptionHandler można przeanalizować kod web.xml, aby znaleźć lokalizacje stron błędów, utworzyć z nim nowy UIViewRoot i zmusić JSF do ustawienia renderowania ajax'a na @all.

Więc zasadzie:

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

Zobacz także ten powiązane pytanie: What is the correct way to deal with JSF 2.0 exceptions for AJAXified components? i ten blog: Full Ajax Exception Handler.

+0

Czy OmniFaces 'org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory' może być użyty wraz z obsługą wyjątków poprzez utworzenie' ExceptionHandlerFactory' w ten sposób, aby przekierować do globalnych stron błędów, gdy wyjątki są rzucone, które nie są zapakowane przez tę fabrykę? Dokumentacja wymaga tylko jednej fabryki obsługi wyjątków dla każdej aplikacji, "* Musi istnieć jedna instancja' ExceptionHandlerFactory' na aplikację WWW, która wykorzystuje JavaServer Faces.Te wystąpienie można uzyskać w sposób przenośny, wywołując. * "Działa to dobrze przekierowanie na stronie globalnego błędu. – Tiny

+0

@ Tiny: możesz go rozszerzyć. Zobacz także javadoc. Zastąp 'shouldHandleExceptionRootCause()', aby zwrócić 'false' (i dodaj tę fatalną wiadomość). – BalusC

3

Zależy od tego, co chcesz zrobić, gdy otrzymasz ViewExpiredException.

Jeśli chcesz wyświetlić stronę błędu użytkownika, możesz to zrobić tak, jak powiedziałeś.

Ten post pokazuje, jak programowo przechwycić ViewExpiredException i zrobić z nim coś miłego.

+1

link jest zepsuty, proszę dodać działający link, – aName

Powiązane problemy