@Controller va @ControllerAdvice annotatsiya bilan belgilangan klasslar, quyidagi misolda ko'rsatilganidek, istisnolarni nazorat usullarida qayta ishlovchi, @ExceptionHandler annotatsiyasi bilan belgilangan usullarga ega bo'lishi mumkin:
@Controller
public class SimpleController {
// ...
@ExceptionHandler
public ResponseEntity<String> handle(IOException ex) {
// ...
}
}
@Controller
class SimpleController {
// ...
@ExceptionHandler
fun handle(ex: IOException): ResponseEntity<String> {
// ...
}
}
Istisno yuqori darajadagi tarqatilgan istisno bilan (masalan, to'g'ridan-to'g'ri genlangan IOException) yoki istisno-qoplovchi ichidagi sabab bilan mos kelishi mumkin (masalan, IllegalStateException ichidagi IOException). 5.3 versiyasidan boshlab, bu har qanday sabab darajasida mos kelishi mumkin, oldin esa faqat darhol sabab e'tiborga olinardi.
Mos keladigan istisno turlarini metod argumentlari sifatida maqsadga muvofiq deb e'lon qilish tavsiya etiladi, avvalgi misolda ko'rsatilgandek. Bir nechta metodlar istisnolarga mos kelganda, odatda sabab istisnolariga mos kelishdan ko'ra ildiz istisnosiga mos kelish afzalroqdir. Ayniqsa, ExceptionDepthComparator istisnolarni genlangan istisno turidan kelib chiqqan chuqurlikka qarab saralash uchun ishlatiladi.
Bundan tashqari, annotatsiyani e'lon qilish mos kelishi kerak bo'lgan istisnolar turlarini cheklashi mumkin, quyidagi misolda ko'rsatilgandek:
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(IOException ex) {
// ...
}
@ExceptionHandler(FileSystemException::class, RemoteException::class)
fun handle(ex: IOException): ResponseEntity<String> {
// ...
}
Hatto juda umumiy argumentlar imzosi bilan aniq istisno turlarini ro'yxati ham ishlatilishi mumkin, quyidagi misolda ko'rsatilgandek:
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(Exception ex) {
// ...
}
@ExceptionHandler(FileSystemException::class, RemoteException::class)
fun handle(ex: Exception): ResponseEntity<String> {
// ...
}
Ildiz istisnolari va sabab istisnolari orasidagi farq hayratlanarli bo'lishi mumkin.
Oldin ko'rsatilgan IOException variantida, metod odatda FileSystemException yoki RemoteException haqiqiy nusxasi bilan argument sifatida tetiqlanadi, chunki ularning har ikkalasi IOException dan kengaytirilgan. Ammo, agar biror mos keluvchi istisno o'zi IOException bo'lgan istisno-qoplovchi ichida tarqatilsa, o'tkazilgan istisno nusxasi shu qoplovchi istisno bo'ladi.
handle(Exception) variantida ishlash logikasi yanada sodda. Qoplanish ssenariysida qoplamali istisno orqali tetiqlanadi, bu holatda haqiqiy mos keluvchi istisno ex.getCause() orqali topilishi mumkin. Istisno FileSystemException yoki RemoteException ning haqiqiy nusxasi sifatida faqat ular yuqori darajali istisnolar sifatida genlangan bo'lsa o'tkaziladi.
Odatda, iloji boricha ko'proq konkretlik kiritish tavsiya etiladi, bu ildiz va sabab istisno turlari o'rtasidagi mos kelish ehtimolini kamaytiradi. Bir necha mos kelishli metodlarni alohida-alohida @ExceptionHandler annotatsiyalangan metodlarga ajratish imkoniyatini ko'rib chiqing, ularning har biri o'zining imzosi orqali bitta aniqlangan istisno turiga mos keladi.
Bir nechta @ControllerAdvice annotatsiyalari bilan konfiguratsiyada, biz asosiy ildiz istisnolarini @ControllerAdvice annotatsiyasi orqali mos kelishini e'lon qilishni tavsiya qilamiz, ularni tegishli ustuvorlik tartibida. Garchi ildiz istisnolariga mos kelish afzalroq bo'lsa-da, mos kelish mavjud nazorat metodlari yoki @ControllerAdvice annotatsiyalangan klasslar orasida amalga oshiriladi. Bu shuni anglatadiki, yuqori ustuvorlikka ega @ControllerAdvice annotatsiyalangan bin uchun sababga mos kelish, pastroq ustuvorlikka ega @ControllerAdvice annotatsiyalangan bin uchun har qanday mos kelishdan (masalan, ildiz) afzallik beradi.
Oxirgi, ammo kam muhim emas: @ExceptionHandler annotatsiyalangan metodning amalga oshirilishi berilgan istisno nusxasini qayta genlash orqali dastlabki shaklda ishlashdan voz kechishi mumkin. Bu faqat ildiz darajasidagi mos kelishlarni yoki statik tarzda belgilanmaydigan kontekstda mos kelishlarni qiziqtirilgan holatlarda foydali bo'ladi. Istisnomani qayta genlash qolgan ruxsat berish zanjiri bo'yicha tarqatiladi, xuddi shu metod @ExceptionHandler annotatsiyasiga mos kelmaganidek.
Spring MVC'dagi @ExceptionHandler annotatsiyalangan metodlarini qo'llab-quvvatlash DispatcherServlet, HandlerExceptionResolver mexanizmi darajasida yaratilgan.
Metod argumentlari
@ExceptionHandler bilan annotatsiyalangan metodlar quyidagi argumentlarni qo'llab-quvvatlaydi:
| Metod Argumenti | Tavsif |
|---|---|
| Istisno turi |
Genlangan istisnoga kirish imkoniyatini beradi. |
|
|
Istisnoni genlagan nazorat metodiga kirish imkoniyatini beradi. |
|
|
Servlet API'nidan to'g'ridan-to'g'ri foydalanmasdan so'rov parametrlariga va sessiya atributlariga tipik kirish imkoniyatini beradi. |
|
|
Har qanday konkret so'rov yoki javob turini tanlang (masalan, |
|
|
Sessiyaning mavjudligini ta'minlaydi. Natijada, bunday argument hech qachon |
|
|
Hozirgi autentifikatsiya qilingan foydalanuvchi – ehtimol, agar u ma'lum bo'lsa, |
|
|
HTTP-so'rov metodi. |
|
|
Hozirgi so'rovga tegishli mavjud eng aniq |
|
|
|
|
|
Servlet API orqali belgilangan javobning xom tanasiga kirish imkoniyatini beradi. |
|
|
Xato javobini chiqarish uchun modelga kirish imkoniyatini beradi. Har doim bo'sh. |
|
|
To'plangan |
|
|
Sessiyada saqlangan model atributlaridan farqli o'laroq, sessiyadagi har qanday atributga kirish imkoniyatini ta'minlash uchun mo'ljallangan. |
|
|
So'rov atributlariga kirish imkoniyatini ta'minlash uchun mo'ljallangan. |
Qaytarish qiymatlari
@ExceptionHandler bilan annotatsiyalangan metodlar quyidagi qaytarish qiymatlarini qo'llab-quvvatlaydi:
| Qaytarish qiymati | Tavsif |
|---|---|
|
|
Qaytarish qiymati |
|
|
Qaytarish qiymati to'liq javobni (shu jumladan HTTP-qo'shimcha va tanasini) |
|
|
Ko'rinish nomi, |
|
|
Ko'rinish nusxasi, implicit model bilan birgalikda ko'rish uchun mo'ljallangan – bu |
|
|
Ko'rinish nomini, |
|
|
Modelga, Eslatma, |
|
|
Ko'rinish va modellashtirilgan atributlar va, kerak bo'lsa, javob holati. |
|
|
U Agar yuqorida aytilgan hech biri to'g'ri bo'lmasa, |
| Boshqa har qanday qaytarish qiymati |
Agar qaytarish qiymati yuqorida aytilganlardan hech biriga mos kelmasa va oddiy tur bo'lmasa (quyidagi BeanUtils#isSimpleProperty bilan aniqlangan), u sukut bo'yicha modellashtirilgan atribut deb hisoblanadi, u modelga qo'shilishi kerak. Agar bu oddiy tur bo'lsa, u yechim topilmaydi. |
REST APIda istisnolar bilan ishlash
REST xizmatlari uchun umumiy talablardan biri javob tanasiga xato ma'lumotlarini qo'shishdir. Spring Framework avtomatik ravishda buni qilmaydi, chunki xato ma'lumotlarini javob tanasida taqdim etish dasturga xosdir. Ammo, @RestController annotatsiyalangan metodlar, javob holati va tanasini o'rnatish uchun ResponseEntity qaytarish qiymatidan foydalanishi mumkin. Bunday metodlar, shuningdek, global miqyosda qo'llanilishi uchun @ControllerAdvice bilan annotatsiyalashgan klasslarda e'lon qilinishi mumkin.
Javob tanasida batafsil xato tavsifi bilan global istisnolarni qayta ishlashni amalga oshiruvchi ilovalar, Spring MVC'da yuzaga kelgan istisnolarni qayta ishlashni ta'minlaydigan va javob tanasini konfiguratsiya qilish uchun tutib olish usullarini taqdim etuvchi ResponseEntityExceptionHandler imkoniyatlarini kengaytirishni ko'rib chiqishi kerak. Buning uchun, ResponseEntityExceptionHandlerni subclass qilib oling, uni @ControllerAdvice bilan annotatsiyalang, kerakli metodlarni qayta belgilang va uni Spring bean sifatida e'lon qiling.
GO TO FULL VERSION