Jawaban baru (2016-04-20)
Menggunakan Spring Boot 1.3.1.RELEASE
Langkah Baru 1 - Mudah dan tidak terlalu mengganggu untuk menambahkan properti berikut ke aplikasi.properti:
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
Jauh lebih mudah daripada memodifikasi instance DispatcherServlet yang ada (seperti di bawah ini)! - JO '
Jika bekerja dengan Aplikasi RESTful penuh, sangat penting untuk menonaktifkan pemetaan otomatis sumber daya statis karena jika Anda menggunakan konfigurasi default Spring Boot untuk menangani sumber daya statis maka penangan sumber daya akan menangani permintaan (itu dipesan terakhir dan dipetakan ke / ** yang artinya menerima permintaan yang belum ditangani oleh penangan lain dalam aplikasi) sehingga servlet pengirim tidak mendapat kesempatan untuk melemparkan pengecualian.
Jawaban Baru (2015-12-04)
Menggunakan Spring Boot 1.2.7.RELEASE
Langkah Baru 1 - Saya menemukan cara yang tidak terlalu mengganggu untuk mengatur flag "throExceptionIfNoHandlerFound". Ganti kode penggantian DispatcherServlet di bawah ini (Langkah 1) dengan ini di kelas inisialisasi aplikasi Anda:
@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);
}
Dalam hal ini, kami menetapkan bendera pada DispatcherServlet yang ada, yang mempertahankan setiap konfigurasi otomatis oleh kerangka Boot Spring.
Satu hal lagi yang saya temukan - penjelasan @EnableWebMvc mematikan Spring Boot. Ya, anotasi itu memungkinkan hal-hal seperti bisa menangkap semua pengecualian controller seperti dijelaskan di bawah, tetapi juga membunuh BANYAK konfigurasi otomatis yang bermanfaat yang biasanya diberikan oleh Spring Boot. Gunakan anotasi itu dengan sangat hati-hati saat Anda menggunakan Spring Boot.
Jawaban asli:
Setelah banyak penelitian dan menindaklanjuti solusi yang diposting di sini (terima kasih atas bantuannya!) Dan tidak ada jumlah kecil runtime menelusuri ke kode Spring, saya akhirnya menemukan konfigurasi yang akan menangani semua Pengecualian (bukan Kesalahan, tetapi baca terus) termasuk 404-an.
Langkah 1 - beri tahu SpringBoot untuk berhenti menggunakan MVC untuk situasi "handler not found". Kami ingin Spring melempar pengecualian alih-alih kembali ke klien, pandangan dialihkan ke "/ kesalahan". Untuk melakukan ini, Anda harus memiliki entri di salah satu kelas konfigurasi Anda:
// 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;
}
}
Kelemahan dari ini adalah bahwa ia menggantikan servlet pengirim standar. Ini belum menjadi masalah bagi kami, tanpa ada efek samping atau masalah eksekusi yang muncul. Jika Anda akan melakukan hal lain dengan servlet operator karena alasan lain, ini adalah tempat untuk melakukannya.
Langkah 2 - Sekarang boot spring akan mengeluarkan eksepsi ketika tidak ada handler yang ditemukan, eksepsi itu dapat ditangani dengan yang lain dalam handler eksepsi yang disatukan:
@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);
}
...
}
Perlu diingat bahwa saya pikir anotasi "@EnableWebMvc" penting di sini. Tampaknya tidak ada yang berhasil tanpa itu. Dan itu saja - aplikasi boot Spring Anda sekarang akan menangkap semua pengecualian, termasuk 404, di kelas handler di atas dan Anda dapat melakukannya dengan sesuka Anda.
Satu poin terakhir - sepertinya tidak ada cara untuk mendapatkan ini untuk menangkap kesalahan yang dilemparkan. Saya memiliki ide aneh untuk menggunakan aspek-aspek untuk menangkap kesalahan dan mengubahnya menjadi Pengecualian yang dapat ditangani oleh kode di atas, tetapi saya belum punya waktu untuk benar-benar mencoba mengimplementasikannya. Semoga ini bisa membantu seseorang.
Setiap komentar / koreksi / peningkatan akan dihargai.