Istisnolar

All lectures for UZ purposes
Daraja, Dars
Mavjud

@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:

Java
@Controller
public class SimpleController {
    // ...
    @ExceptionHandler
    public ResponseEntity<String> handle(IOException ex) {
        // ...
    }
}
Kotlin
@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:

Java
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(IOException ex) {
    // ...
}
Kotlin
@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:

Java
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(Exception ex) {
    // ...
}
Kotlin
@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.

HandlerMethod

Istisnoni genlagan nazorat metodiga kirish imkoniyatini beradi.

WebRequest, NativeWebRequest

Servlet API'nidan to'g'ridan-to'g'ri foydalanmasdan so'rov parametrlariga va sessiya atributlariga tipik kirish imkoniyatini beradi.

javax.servlet.ServletRequest, javax.servlet.ServletResponse

Har qanday konkret so'rov yoki javob turini tanlang (masalan, ServletRequest yoki HttpServletRequest, yoki MultipartRequest yoki Spring'ning MultipartHttpServletRequest).

javax.servlet.http.HttpSession

Sessiyaning mavjudligini ta'minlaydi. Natijada, bunday argument hech qachon null emas.
Unutmang, sessiyaga kirish o'zgaruvchan emas. Agar bir nechta so'rovlarga sessiyaga bir vaqtning o'zida kirishga ruxsat berilsa, RequestMappingHandlerAdapter nusxasining synchronizeOnSession bayrog'ini true ga o'rnatish imkoniyatini ko'rib chiqing.

java.security.Principal

Hozirgi autentifikatsiya qilingan foydalanuvchi – ehtimol, agar u ma'lum bo'lsa, Principalning aniq amalga oshirish klassi.

HttpMethod

HTTP-so'rov metodi.

java.util.Locale

Hozirgi so'rovga tegishli mavjud eng aniq LocaleResolver orqali aniqlangan mintaqa sozlamalari – asosan, sozlangan LocaleResolver yoki LocaleContextResolver.

java.util.TimeZone, java.time.ZoneId

LocaleContextResolver tomonidan aniqlangan, hozirgi so'rov bilan bog'liq vaqt zonasi.

java.io.OutputStream, java.io.Writer

Servlet API orqali belgilangan javobning xom tanasiga kirish imkoniyatini beradi.

java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap

Xato javobini chiqarish uchun modelga kirish imkoniyatini beradi. Har doim bo'sh.

RedirectAttributes

To'plangan flash atributlar va o'tkazishdan so'ng so'rovga qo'shiladigan atributlarni belgilaydi.

@SessionAttribute

Sessiyada saqlangan model atributlaridan farqli o'laroq, sessiyadagi har qanday atributga kirish imkoniyatini ta'minlash uchun mo'ljallangan.

@RequestAttribute

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

@ResponseBody

Qaytarish qiymati HttpMessageConverter nusxalari orqali konvertatsiya qilinadi va javobga yoziladi.

HttpEntity<B>, ResponseEntity<B>

Qaytarish qiymati to'liq javobni (shu jumladan HTTP-qo'shimcha va tanasini) HttpMessageConverter nusxalari orqali konvertatsiya qiladi va javobga yozadi.

String

Ko'rinish nomi, ViewResolver amalga oshirilishlarini tan olinish kerak va @ModelAttribute bilan belgilangan komanda ob'ektlari va metodlar orqali aniqlangan implicit model bilan ishlatiladi. Metod shuningdek, Model argumentini e'lon qilish orqali modelni dasturiy ravishda qayta ishlashi mumkin (oldinroq tavsiflangan).

View

Ko'rinish nusxasi, implicit model bilan birgalikda ko'rish uchun mo'ljallangan – bu @ModelAttribute annotatsiyalangan komanda ob'ektlari va metodlar orqali aniqlangan. Metod shuningdek, Model argumentini e'lon qilish orqali modelni dasturiy ravishda qayta ishlashi mumkin (oldinroq tavsiflangan).

java.util.Map, org.springframework.ui.Model

Ko'rinish nomini, RequestToViewNameTranslator orqali implicit ravishda aniqlangan, aniqlangan modellashtirilgan atributlar.

@ModelAttribute

Modelga, RequestToViewNameTranslator orqali implicit ravishda aniqlangan ko'rinish nomi bilan qo'shiladigan atribut.

Eslatma, @ModelAttribute annotatsiyasi ixtiyoriydir. Ushbu jadvalning oxiridagi "Boshqa har qanday qaytarish qiymati" bo'limiga qarang.

ModelAndView ob'ekti

Ko'rinish va modellashtirilgan atributlar va, kerak bo'lsa, javob holati.

void

U ServletResponse yoki OutputStream argumentiga ega yoki @ResponseStatus annotatsiyalanadi, javob to'liq qo'llandi deb hisoblanadi. Xuddi shu nazorat ETag yoki lastModified vaqt belgisiga ijobiy mos kelgan bo'lsa, bu o'zgaruvsiz qoladi.

Agar yuqorida aytilgan hech biri to'g'ri bo'lmasa, void qaytarish turi REST-nazoratlar uchun "javob tanasi yo'q" yoki HTML-nazoratlar uchun sukut bo'yicha ko'rinish nomini tanlashni bildirishi mumkin.

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.

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION