2011-11-25 40 views
13

Tôi đang sử dụng SimpleMappingExceptionResolver gửi tất cả các ngoại lệ đến một chế độ xem được hiển thị độc đáo. Nó hoạt động ngoại trừ một trường hợp: Nếu người dùng yêu cầu một trang và sau đó gửi và "Hủy bỏ" (Tôi không biết chính xác cách hoạt động, nhưng tôi nhận thấy rằng nếu tôi nhấp vào nút gửi biểu mẫu bài đăng HTTP rất nhanh và thường xuyên Firefox 7 bằng cách nào đó thông báo cho máy chủ rằng nó không còn quan tâm đến kết quả.) Sau đó, Tomcat 6 tăng ClientAbortException khi một cố gắng hiển thị trang hoặc viết câu trả lời http dưới bất kỳ hình thức nào.Làm cách nào để loại trừ ClientAbortException khỏi SimpleMappingExceptionResolver

Bây giờ, hãy bắt đầu sự cố: SimpleMappingExceptionResolver "bắt" ngoại lệ và truy xuất để hiển thị số độc đáo thành trang html. Điều này sau đó gây ra trong một ngoại lệ Stream đã đóng mà gây ô nhiễm tệp nhật ký. (java.lang.IllegalStateException: getOutputStream() has already been called for this response)

Những gì tôi đã làm như vậy, là đăng ký một trang jsp trống cho "ClientAbortException". Nhưng tôi cảm thấy rằng đây là một Hack. Mặt khác, tôi đoán đây không phải là một vấn đề không phổ biến, bởi vì tôi sẽ mong đợi nó trong gần như mọi ứng dụng mùa xuân mà ám chỉ tất cả ngoại lệ. Vì vậy, không ai có kinh nghiệm với vấn đề đó, hoặc có một ý tưởng về một giải pháp không nên hacky?

<bean 
    class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" 
    p:defaultErrorView="uncaughtException"> 
    <property name="exceptionMappings"> 
     <props> 
      <prop key=".MissingServletRequestParameterException"> 
       resourceNotFound 
      </prop> 
      <prop key=".ClientAbortException">nothing</prop> 
     </props> 
    </property> 
</bean> 

Trả lời

10

Mở rộng SimpleMappingExceptionResolver, ghi đè doResolveException() phương pháp, và trong trường hợp tên ngoại lệ là ClientAbortExceptionresponse.isCommitted() trở null thay vì trả lại super.doResolveException().

1

IMHO, đăng ký chế độ xem nothing cho số Exception bạn không muốn xử lý là cách thanh lịch; trái với cảm giác hack; vì bạn có thể có nhiều hơn một ngoại lệ bạn không/sẽ không muốn hiển thị so với các ngoại lệ khác.

Tôi sẽ không khuyên bạn nên đưa ra triển khai tùy chỉnh cho HandlerExceptionResolver; vì nó có thể làm tăng chi phí bảo trì.

1

Đối với phiên bản mới hơn của Mùa xuân, bạn cũng có thể sử dụng chú thích @ExceptionHandler, có thể với @ControllerAdvice (để xử lý toàn cầu).

@ControllerAdvice 
public class GlobalDefaultExceptionHandler { 
    private final Logger logger = LoggerFactory.getLogger(getClass()); 

    @ExceptionHandler(ClientAbortException.class) 
    public void clientAbortExceptionHandler(HttpServletRequest request, ClientAbortException e) { 
     // This usually means the browser closed or disconnected or 
     // something. We can't do anything. To avoid excessive stack traces 
     // in log, just print a simple message and return null 
     String username = "<NONE>"; 
     Principal principal = request.getUserPrincipal(); 
     if (principal != null) { 
      username = principal.getName(); 
     } 
     logger.warn("ClientAbortException: username={},remoteAddr={},userAgent={},requestedURL={}", username, 
       request.getRemoteAddr(), request.getHeader("User-Agent"), request.getRequestURL()); 
    } 

} 
+1

Đối với tôi, tính năng này không hoạt động. Phương thức này không bao giờ được gọi khi chạy trong tomcat ... – membersound

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