2012-05-10 21 views
22

Tất cả các ExceptionHandlerFactory ví dụ tôi đã đi qua cho đến nay chuyển hướng người dùng đến một trang viewExpired.jsf trong trường hợp một ViewExpiredException bị bắt:Tại sao sử dụng JSF ExceptionHandlerFactory thay vì chuyển hướng <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(); 
    } 
} 

Dường như với tôi rằng web.xml cấu hình sau đây đơn giản về cơ bản là giống nhau và đơn giản hơn nhiều:

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

Điều này sẽ nhắc câu hỏi - tại sao một người sử dụng ExceptionHandlerFactory?

+0

Mã phía trên của bạn phải không? nếu không, bạn có thể ghi có nguồn không? Liên kết – Mindwin

Trả lời

23

Các ví dụ cụ thể không chỉ có một điều hữu ích: nó tiết kiệm ID chế độ xem như một thuộc tính yêu cầu để bạn có thể sử dụng ví dụ

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

Nhưng điều này không phải là vô cùng hữu ích như yêu cầu liệu URI đã có sẵn theo thuộc tính yêu cầu mặc định javax.servlet.error.request_uri của <error-page>.

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

Tuy nhiên có một điều gì một tùy chỉnh ExceptionHandler là thực sự hữu ích cho là nó cho phép bạn để đối phó với trường hợp ngoại lệ trong ajax yêu cầu. Theo mặc định, họ có cụ thể là không có hình thức duy nhất của thông tin phản hồi hữu ích ở phía khách hàng. Chỉ trong Mojarra với giai đoạn dự án được đặt thành "Phát triển", bạn sẽ thấy thông báo cảnh báo JavaScript trống với thông báo ngoại lệ. Nhưng kia là nó. Không có hình thức phản hồi nào trong giai đoạn "Sản xuất". Với tùy chỉnh ExceptionHandler bạn có thể phân tích cú pháp web.xml để tìm các vị trí trang lỗi, tạo UIViewRoot mới với nó và buộc JSF đặt kết xuất ajax thành @all.

Vì vậy, về cơ bản :

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

cũng Xem câu hỏi liên quan này: What is the correct way to deal with JSF 2.0 exceptions for AJAXified components? và blog này: Full Ajax Exception Handler.

+0

Có thể sử dụng OmniFaces 'org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory' cùng với xử lý ngoại lệ bằng cách tạo một' ExceptionHandlerFactory' theo cách này để chuyển hướng đến (các) trang lỗi toàn cầu, khi ngoại lệ ném mà không được bao bọc bởi nhà máy này? Tài liệu này chỉ yêu cầu một nhà máy xử lý ngoại lệ cho mỗi ứng dụng, "* Phải có một cá thể' ExceptionHandlerFactory' cho mỗi ứng dụng web đang sử dụng các khuôn mặt JavaServer. Ví dụ này có thể được mua một cách di động bằng cách gọi. * " đến một trang lỗi toàn cầu, nhân tiện. – Tiny

+0

@Tiny: bạn có thể mở rộng nó. Xem thêm javadoc. Ghi đè 'shouldHandleExceptionRootCause()' để trả về 'false' (và thêm thông điệp chết người đó). – BalusC

3

Tùy thuộc vào việc bạn muốn làm gì khi bạn recive ViewExpiredException.

Nếu bạn chỉ muốn hiển thị trang lỗi người dùng, bạn có thể làm như bạn đã nói.

Điều này post cho bạn biết cách chặn theo chương trình ViewExpiredException và làm điều gì đó tuyệt vời với nó.

+1

bị hỏng, vui lòng thêm liên kết hoạt động, – aName

Các vấn đề liên quan