Câu trả lời mới (2016-04-20)
Sử dụng Spring Boot 1.3.1.RELEASE
Bước 1 mới - Thật dễ dàng và ít xâm phạm để thêm các thuộc tính sau vào application.properations:
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
Dễ dàng hơn nhiều so với sửa đổi phiên bản DispatcherServlet hiện tại (như bên dưới)! - JO '
Nếu làm việc với Ứng dụng RESTful đầy đủ, điều rất quan trọng là vô hiệu hóa ánh xạ tự động của tài nguyên tĩnh vì nếu bạn đang sử dụng cấu hình mặc định của Spring Boot để xử lý tài nguyên tĩnh thì trình xử lý tài nguyên sẽ xử lý yêu cầu (được yêu cầu cuối cùng và được ánh xạ tới / ** có nghĩa là nó nhận bất kỳ yêu cầu nào chưa được xử lý bởi bất kỳ trình xử lý nào khác trong ứng dụng), do đó, bộ điều phối servlet không có cơ hội ném ngoại lệ.
Câu trả lời mới (2015-12-04)
Sử dụng Spring Boot 1.2.7.RELEASE
Bước 1 mới - Tôi đã tìm thấy một cách ít xâm phạm hơn để thiết lập cờ "throException IfNoHandlerFound". Thay thế mã thay thế của DispatcherServlet bên dưới (Bước 1) bằng mã này trong lớp khởi tạo ứng dụng của bạn:
@ComponentScan()
@EnableAutoConfiguration
public class MyApplication extends SpringBootServletInitializer {
private static Logger LOG = LoggerFactory.getLogger(MyApplication.class);
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
DispatcherServlet dispatcherServlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
}
Trong trường hợp này, chúng tôi sẽ đặt cờ trên DispatcherServlet hiện có, bảo tồn mọi cấu hình tự động theo khung Spring Boot.
Một điều nữa tôi đã tìm thấy - chú thích @EnableWebMvc gây chết người cho Spring Boot. Đúng, chú thích đó cho phép những thứ như có thể bắt được tất cả các ngoại lệ của bộ điều khiển như được mô tả bên dưới, nhưng nó cũng giết rất nhiều cấu hình tự động hữu ích mà Spring Boot thường cung cấp. Sử dụng chú thích đó hết sức thận trọng khi bạn sử dụng Spring Boot.
Câu trả lời gốc:
Sau rất nhiều nghiên cứu và theo dõi các giải pháp được đăng ở đây (cảm ơn vì đã giúp đỡ!) Và một lượng nhỏ thời gian chạy theo mã Spring, cuối cùng tôi đã tìm thấy một cấu hình sẽ xử lý tất cả Ngoại lệ (không phải Lỗi, nhưng đọc tiếp) bao gồm 404s.
Bước 1 - yêu cầu SpringBoot ngừng sử dụng MVC cho các tình huống "không tìm thấy trình xử lý". Chúng tôi muốn Spring ném một ngoại lệ thay vì quay lại máy khách chuyển hướng xem sang "/ error". Để làm điều này, bạn cần có một mục trong một trong các lớp cấu hình của bạn:
// NEW CODE ABOVE REPLACES THIS! (2015-12-04)
@Configuration
public class MyAppConfig {
@Bean // Magic entry
public DispatcherServlet dispatcherServlet() {
DispatcherServlet ds = new DispatcherServlet();
ds.setThrowExceptionIfNoHandlerFound(true);
return ds;
}
}
Nhược điểm của việc này là nó thay thế cho servlet bộ điều phối mặc định. Đây chưa phải là vấn đề đối với chúng tôi, không có tác dụng phụ hoặc vấn đề thực thi nào xuất hiện. Nếu bạn định làm bất cứ điều gì khác với servlet điều phối vì những lý do khác, thì đây là nơi để thực hiện chúng.
Bước 2 - Bây giờ khởi động mùa xuân sẽ đưa ra một ngoại lệ khi không tìm thấy trình xử lý nào, ngoại lệ đó có thể được xử lý với bất kỳ trình xử lý ngoại lệ hợp nhất nào:
@EnableWebMvc
@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(Throwable.class)
@ResponseBody
ResponseEntity<Object> handleControllerException(HttpServletRequest req, Throwable ex) {
ErrorResponse errorResponse = new ErrorResponse(ex);
if(ex instanceof ServiceException) {
errorResponse.setDetails(((ServiceException)ex).getDetails());
}
if(ex instanceof ServiceHttpException) {
return new ResponseEntity<Object>(errorResponse,((ServiceHttpException)ex).getStatus());
} else {
return new ResponseEntity<Object>(errorResponse,HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
Map<String,String> responseBody = new HashMap<>();
responseBody.put("path",request.getContextPath());
responseBody.put("message","The URL you have reached is not in service at this time (404).");
return new ResponseEntity<Object>(responseBody,HttpStatus.NOT_FOUND);
}
...
}
Hãy nhớ rằng tôi nghĩ chú thích "@EnableWebMvc" có ý nghĩa ở đây. Có vẻ như không ai trong số này làm việc mà không có nó. Và đó là - ứng dụng khởi động Spring của bạn bây giờ sẽ bắt được tất cả các ngoại lệ, bao gồm 404, trong lớp xử lý ở trên và bạn có thể làm với chúng khi bạn muốn.
Một điểm cuối cùng - dường như không có cách nào để có được điều này để bắt lỗi ném. Tôi có một ý tưởng kỳ quặc là sử dụng các khía cạnh để bắt lỗi và biến chúng thành Ngoại lệ mà đoạn mã trên có thể xử lý, nhưng tôi chưa có thời gian để thực sự thử thực hiện điều đó. Hy vọng điều này sẽ giúp được ai đó.
Bất kỳ ý kiến / sửa chữa / cải tiến sẽ được đánh giá cao.