Saya ingin menggunakan cara umum untuk mengelola kode kesalahan 5xx, katakanlah secara khusus kasus ketika db turun di seluruh aplikasi pegas saya. Saya ingin json error cantik, bukan pelacakan tumpukan.
Untuk pengontrol saya memiliki @ControllerAdvice
kelas untuk pengecualian yang berbeda dan ini juga menangkap kasus bahwa db berhenti di tengah permintaan. Tapi ini tidak semua. Saya juga kebetulan memiliki CorsFilter
perpanjangan khusus OncePerRequestFilter
dan di sana ketika saya menelepon doFilter
saya mendapatkan CannotGetJdbcConnectionException
dan itu tidak akan dikelola oleh@ControllerAdvice
. Saya membaca beberapa hal secara online yang hanya membuat saya semakin bingung.
Jadi saya punya banyak pertanyaan:
- Apakah saya perlu menerapkan filter kustom? Saya menemukan
ExceptionTranslationFilter
tapi ini hanya menanganiAuthenticationException
atauAccessDeniedException
. - Saya berpikir untuk menerapkannya sendiri
HandlerExceptionResolver
, tetapi ini membuat saya ragu, saya tidak memiliki pengecualian khusus untuk dikelola, pasti ada cara yang lebih jelas dari ini. Saya juga mencoba menambahkan coba / menangkap dan memanggil implementasiHandlerExceptionResolver
(harus cukup baik, pengecualian saya tidak ada yang istimewa) tetapi ini tidak mengembalikan apa pun dalam respons, saya mendapatkan status 200 dan badan kosong.
Apakah ada cara yang baik untuk mengatasi ini? Terima kasih
sumber
Jawaban:
Jadi inilah yang saya lakukan:
Saya membaca dasar-dasar tentang filter di sini dan saya menemukan bahwa saya perlu membuat filter khusus yang akan menjadi yang pertama dalam rantai filter dan akan mencoba menangkap semua pengecualian runtime yang mungkin terjadi di sana. Kemudian saya perlu membuat json secara manual dan memasukkannya ke dalam respons.
Jadi, inilah filter khusus saya:
Dan kemudian saya menambahkannya di web.xml sebelum
CorsFilter
. Dan berhasil!sumber
Saya ingin memberikan solusi berdasarkan jawaban @kopelitsa . Perbedaan utamanya adalah:
HandlerExceptionResolver
.Pertama, Anda perlu memastikan, bahwa Anda memiliki kelas yang menangani pengecualian yang terjadi di RestController / Controller biasa (kelas yang dianotasi dengan
@RestControllerAdvice
atau@ControllerAdvice
dan metode yang dianotasi@ExceptionHandler
). Ini menangani pengecualian Anda yang terjadi di pengontrol. Berikut adalah contoh menggunakan RestControllerAdvice:Untuk menggunakan kembali perilaku ini di rantai filter Keamanan Musim Semi, Anda perlu menentukan Filter dan mengaitkannya ke konfigurasi keamanan Anda. Filter perlu mengalihkan pengecualian ke penanganan pengecualian yang ditentukan di atas. Berikut ini contohnya:
Filter yang dibuat kemudian perlu ditambahkan ke SecurityConfiguration. Anda harus mengaitkannya ke rantai lebih awal, karena semua pengecualian filter sebelumnya tidak akan tertangkap. Dalam kasus saya, masuk akal untuk menambahkannya sebelum
LogoutFilter
. Lihat rantai filter default dan urutannya di dokumen resmi . Berikut ini contohnya:sumber
Saya menemukan masalah ini sendiri dan saya melakukan langkah-langkah di bawah ini untuk menggunakan kembali masalah saya
ExceptionController
yang dianotasi@ControllerAdvise
untukExceptions
dimasukkan ke dalam Filter terdaftar.Jelas ada banyak cara untuk menangani pengecualian tetapi, dalam kasus saya, saya ingin pengecualian ditangani oleh saya
ExceptionController
karena saya keras kepala dan juga karena saya tidak ingin menyalin / menempel kode yang sama (yaitu saya memiliki beberapa pemrosesan / logging kode masukExceptionController
). Saya ingin mengembalikanJSON
respons yang indah seperti pengecualian lainnya yang tidak ditampilkan dari Filter.Bagaimanapun, saya berhasil memanfaatkan saya
ExceptionHandler
dan saya harus melakukan sedikit tambahan seperti yang ditunjukkan di bawah ini dalam langkah-langkah:Langkah
@ControllerAdvise
yaitu MyExceptionControllerKode sampel
Dan sekarang contoh Pengontrol Pegas yang menangani
Exception
kasus normal (yaitu pengecualian yang biasanya tidak dilemparkan di level Filter, yang ingin kita gunakan untuk pengecualian yang dilemparkan ke Filter)Berbagi solusi dengan mereka yang ingin menggunakan
ExceptionController
untukExceptions
dimasukkan ke dalam Filter.sumber
@Component
kelasnya sendiri dan menggunakannya di Filter dan di Pengendali.answer
ini adalah salah satu caranya! Saya belum mengklaim bahwa itu adalah cara terbaik. Terima kasih telah berbagi kepedulian Anda @psv Saya yakin komunitas akan menghargai solusi yang Anda pikirkan :)Jadi, inilah yang saya lakukan berdasarkan penggabungan jawaban di atas ... Kami sudah memiliki
GlobalExceptionHandler
anotasi@ControllerAdvice
dan saya juga ingin menemukan cara untuk menggunakan kembali kode tersebut untuk menangani pengecualian yang berasal dari filter.Solusi paling sederhana yang dapat saya temukan adalah membiarkan pengendali pengecualian saja, dan menerapkan pengontrol kesalahan sebagai berikut:
Jadi, setiap kesalahan yang disebabkan oleh pengecualian terlebih dahulu melewati
ErrorController
dan diarahkan kembali ke pengendali pengecualian dengan mengembalikannya dari dalam@Controller
konteks, sedangkan kesalahan lain (tidak disebabkan secara langsung oleh pengecualian) melewatiErrorController
tanpa modifikasi.Ada alasan mengapa ini sebenarnya ide yang buruk?
sumber
@Override public String getErrorPath() { return null; }
Jika Anda menginginkan cara yang umum, Anda dapat menentukan halaman kesalahan di web.xml:
Dan tambahkan pemetaan di Spring MVC:
sumber
Ini adalah solusi saya dengan mengesampingkan Spring Boot / penanganan kesalahan default
sumber
Hanya untuk melengkapi jawaban bagus lainnya yang diberikan, karena saya juga baru-baru ini menginginkan satu komponen penanganan kesalahan / pengecualian dalam aplikasi SpringBoot sederhana yang berisi filter yang dapat memunculkan pengecualian, dengan pengecualian lain yang berpotensi dilemparkan dari metode pengontrol.
Untungnya, tampaknya tidak ada yang menghalangi Anda untuk menggabungkan saran pengontrol Anda dengan penggantian penangan kesalahan default Spring untuk memberikan muatan respons yang konsisten, memungkinkan Anda untuk berbagi logika, memeriksa pengecualian dari filter, menjebak pengecualian layanan tertentu, dll.
Misalnya
sumber
Ketika Anda ingin menguji keadaan aplikasi dan jika terjadi masalah, kembalikan kesalahan HTTP, saya akan menyarankan filter. Filter di bawah menangani semua permintaan HTTP. Solusi terpendek di Spring Boot dengan filter javax.
Dalam implementasinya bisa bermacam-macam kondisi. Dalam kasus saya, applicationManager menguji apakah aplikasi sudah siap.
sumber
Setelah membaca metode berbeda yang disarankan dalam jawaban di atas, saya memutuskan untuk menangani pengecualian otentikasi dengan menggunakan filter khusus. Saya dapat menangani status dan kode respons menggunakan kelas respons kesalahan menggunakan metode berikut.
Saya membuat filter kustom dan memodifikasi konfigurasi keamanan saya dengan menggunakan metode addFilterAfter dan ditambahkan setelah kelas CorsFilter.
Kelas SecurityConfig
Kelas ErrorResponse
sumber
Anda dapat menggunakan metode berikut di dalam blok tangkapan:
Perhatikan bahwa Anda dapat menggunakan kode HttpStatus dan pesan khusus.
sumber
Aneh karena @ControllerAdvice seharusnya berfungsi, apakah Anda menangkap Exception yang benar?
Coba juga untuk menangkap pengecualian ini di CorsFilter dan mengirim 500 kesalahan, seperti ini
sumber
Filter
mungkin tidak tertangkap@ControllerAdvice
karena in mungkin tidak terjangkauDispatcherServlet
.Anda tidak perlu membuat Filter khusus untuk ini. Kami menyelesaikan ini dengan membuat pengecualian khusus yang memperluas ServletException (yang dilempar dari metode doFilter, ditampilkan dalam deklarasi). Ini kemudian ditangkap dan ditangani oleh penangan kesalahan global kami.
edit: tata bahasa
sumber