JavaRush /Java blogi /Random-UZ /Spring Boot Controllers-da istisnolardan foydalanish

Spring Boot Controllers-da istisnolardan foydalanish

Guruhda nashr etilgan
MAQOLA SIKLINING MAZMUNI Yana bir bor salom! Klaviaturani changdan tozalash vaqti keldi. Spring-boot loyihasini yarating. Maven bog'liqliklaridan bizga kerak:
<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <java.version>1.8</java.version>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.0.RELEASE</version>
    <relativePath/><!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
Batafsil o'qishdan oldin, loyiha tuzilmasini yarating: Bahor yuklash kontrollerlarida istisnolardan foydalanish - 1 BusinessException va CustomException:
public class BusinessException extends Exception{
    public BusinessException(String message) {
        super(message);
    }
}

public class CustomException extends Exception{
    public CustomException(String message) {
        super(message);
    }
}
va Javoblar sinfi
public class Response {

    private String message;

    public Response() {
    }

    public Response(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
Va endi men quloqlarim bilan hiyla qilaman va so'zni Aleksey Kutepovga beraman, o'zining " Bahor boshqaruvchilarida istisnolardan foydalanish" maqolasida u bizga ushbu fayllarni qanday qilib to'g'ri tarkib bilan to'ldirishni aytib beradi. Sekin o'qing, barcha misollarni loyihangizga diqqat bilan ko'chiring, Postman-da ishga tushiring va sinab ko'ring. Agar Alekseyning maqolasida quyidagi satr siz uchun savollar tug'dirgan bo'lsa: ishlab chiqaradi = APPLICATION_JSON_VALUE , bilingki, bu istisnolar bilan ishlashga hech qanday aloqasi yo'q, sukut bo'yicha ushbu kontrollerning barcha usullari JSONni qaytaradi. Agar kerak bo'lsa, ma'lum bir usulda bu qiymat boshqa MediaType- ga bekor qilinishi mumkin.Agar uni o'qigan bo'lsangiz, davom eting. Yuqoridagi maqolada ishlov beruvchilar uchun turli xil variantlar muhokama qilinadi. Ulardan eng moslashuvchani: @ControllerAdvice - bu xatolik yuz berganda standart javobning kodini ham, tanasini ham o'zgartirish imkonini beradi. Bundan tashqari, u bir vaqtning o'zida bir nechta istisnolarni bitta usulda hal qilish imkonini beradi. Ammo bu hammasi emas, agar siz batafsil o'qib chiqsangiz, yaxshilangan @ControllerAdvice-ni mutlaqo bepul olasiz . Keling, tayyorgarlik ishlarini bajaramiz: men javobda odatiy va standart xato xabarlarini ko'rsatishni xohlayman. Buning uchun Response sinfiga o'zgartirish kiritamiz : yana bitta maydon qo'shing
private String debugMessage;
Keling, qo'shimcha konstruktor yarataylik:
public Response(String message, String debugMessage) {
    this.message = message;
    this.debugMessage = debugMessage;
}
va yangi maydon uchun Getter va Setter yaratishni unutmang. Endi nuqtaga. Keling, boshqa kontroller yozamiz:
@RestController
public class Example7Controller {
    @GetMapping(value = "/testExtendsControllerAdvice")
    public ResponseEntity<?> testExtendsControllerAdvice(@RequestBody Response response) {
        return  ResponseEntity.ok(response);
    }
}
Pochtachida sinab ko'raylik: JSON-ni http://localhost:8080/testExtendsControllerAdvice manziliga yuboring
{
    "message": "message"
}
Bunga javoban biz 200 maqomini va tanani olamiz
{
    "message": "message",
    "debugMessage": null
}
Endi biz aniq noto'g'ri JSON yuboramiz
{
    11"message": "message"
}
Bunga javoban biz 400 maqomini olamiz (agar siz bu nimani anglatishini unutgan bo'lsangiz, Internetda qidiring) va bo'sh javob organi. Albatta, bundan hech kim mamnun emas, keling, kurashaylik. Ilgari biz @ControllerAdvice ni noldan yaratgan edik, ammo Spring Boot-da shablon mavjud - ResponseEntityExceptionHandler . U allaqachon ko'plab istisnolarni boshqaradi, masalan: NoHandlerFoundException , HttpMessageNotReadableException , MethodArgumentNotValidException va boshqalar. Bu sinf xatolar bilan shug'ullanadi. Unda bir qancha usullar mavjud, ularning nomlari dastagi + istisno nomi printsipiga asoslanadi . Agar biz ba'zi bir asosiy istisnolarni hal qilmoqchi bo'lsak, biz ushbu sinfdan meros qilib olamiz va kerakli usulni bekor qilamiz . Keling, standart maslahat sinfini yakunlaylik
@ControllerAdvice
public class DefaultAdvice extends ResponseEntityExceptionHandler {//унаследовались от обработчика-заготовки

    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<Response> handleException(BusinessException e) {
        Response response = new Response(e.getMessage());
        return new ResponseEntity<>(response, HttpStatus.OK);
    }
//Небольшое отступление: В обработчике выше, обратите внимание на HttpStatus.OK,
//он может быть и HttpStatus.BAD_REQUEST or другим, тут ограничений нет,
//попробуйте поменять статусы и потестить этот обработчик


    @Override//переопределor метод родительского класса
    protected ResponseEntity<Object> handleHttpMessageNotReadable
            (HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        Response response = new Response("Не правильный JSON",ex.getMessage());
        return new ResponseEntity<>(response, status);
    }
}
Siz sezganingizdek, HttpMessageNotReadableException uchun javobgar ishlov beruvchi bekor qilingan . Ushbu istisno, tekshiruvchi usuliga keladigan so'rovning asosiy qismini o'qib bo'lmaydigan hollarda yuzaga keladi - masalan, noto'g'ri JSON. Ushbu istisno uchun handleHttpMessageNotReadable () usuli javobgardir . Noto'g'ri JSON bilan yana so'rov yuboraylik: http://localhost:8080/testExtendsControllerAdvice
{
    11"message": "message"
}
Biz 400 kodi (Yomon so'rov) va tanasi bilan javob olamiz:
{
    "message": "Не правильный JSON",
    "debugMessage": "JSON parse error: Unexpected character ('1' (code 49)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('1' (code 49)): was expecting double-quote to start field name\n at [Source: (PushbackInputStream); line: 2, column: 6]"
}
Endi javobda nafaqat to'g'ri kod, balki ma'lumot beruvchi xabarlar mavjud. Keling, to'g'ri JSON so'rovi bilan qanday ishlashini tekshirib ko'raylik:
{
    "message": "message"
}
Biz javob oldik:
{
    "message": "message",
    "debugMessage": null
}
Rostini aytsam, javobda null qiymatiga ega maydon borligi menga yoqmaydi , biz buni tezda tuzatamiz. Javoblar sinfiga o'ting va kerakli maydonga izoh qo'ying
@JsonInclude(JsonInclude.Include.NON_NULL)
private String debugMessage;
Biz loyihani qayta ishga tushiramiz, oldingi so'rovni qayta yuboramiz va javobda biz quyidagilarni olamiz:
{
    "message": "message"
}
@JsonInclude(JsonInclude.Include.NON_NULL) izohi tufayli bu maydon faqat biz belgilagan taqdirdagina javobga kiritiladi. @JsonInclude Jekson annotatsiya kutubxonasiga kiritilgan , u nima qila olishini bilish juda foydali. Mana ikkita maqolani tanlash mumkin: Jekson izohlari. Muallif tarjima qildi, lekin tarjimani tugatmadi ; Google Translit ajoyib ish qiladi. Validatsiya Ushbu mavzuni tasdiqlash kabi tushuncha bilan to'ldirish kerak. Oddiy qilib aytganda, bu ob'ekt biz kutgan ob'ekt ekanligini tekshirish. Masalan: agar "Telefon ma'lumotnomasi" ilovasida biz ma'lumotlar bazasida telefon raqamlari mavjudligini tekshirishimiz kerak bo'lsa, unda ma'lumotlar bazasiga kirishdan oldin foydalanuvchi raqamlar o'rniga harflarni kiritganligini tekshirish mantiqan to'g'ri keladi. Tasdiqlash bo'yicha uchta maqola, ortib borayotgan murakkablik: Bahorda loviya tekshiruvi Spring Frameworkda DTO tekshiruvini o'rnatish Spring Boot-da ma'lumotlarni tekshirish Biz bugungi nazariyani tugatdik. Trening uchun men quyidagi vazifani taklif qilaman: NightclubBouncer dasturini amalga oshirishingiz kerak. Talablar: 1) Ilova JSON-ni kirish sifatida qabul qilishi va ma'lumotlar bazasiga yozishi kerak. JSON misoli:
{
    "name": "Katy Perry"
    “status”:super star”
}
Va javob matnida quyidagi yozuv bo'lishi kerak: Xush kelibsiz + ism ! 2) Ilova quyidagi usullarni amalga oshirishi kerak: - ma'lumotlar bazasidan mijozga (Pochtachi) id bo'yicha yozuvni chiqarish. - yozuvni maydon bo'yicha o'chirish: nom . 3) dto qatlamidan ob'ektga va orqaga xaritalash amalga oshirilishi kerak . 4) Ilova KickInTheAssException xatosini chiqarishi kerak (uni oʻzingiz ishlab chiqishingiz kerak), agar kiruvchi JSONdagi holat maydoni quyidagilarga teng boʻlmasa: super yulduz 5) KickInTheAssException xatosi ControllerAdvice tomonidan hal qilinishi kerak va javob korpusida xabar: “Sizni bu yerda boshqa ko‘rishimga ruxsat bermang! Javob holati 400 bo'lishi kerak. 6) EntityNotFoundException standart xatosi , masalan, faqat Katy Perri klubga kelib, id = 1 bilan ma'lumotlar bazasiga saqlangan bo'lsa va siz "id bo'yicha yozuvni ko'rsatish" usulini chaqirgan bo'lsangiz va kerakli bo'lgan bo'lsa, yuzaga keladi. yozuvni ma'lumotlar bazasida bo'lmagan id = 2 bilan ko'rsatish uchun. Bu xato ResponseEntityExceptionHandler sinfining bekor qilingan usuli bilan hal qilinishi kerak , qaysi birini o'zingiz aniqlashingiz kerak. Javob tegishli maqomga ega bo'lishi kerak. 7) Tekshiruvni bajaring: oddiy variant - JSON maydonlari null bo'lmasligi kerak yoki undan ham qiyinroq, "nom" maydoni lotin alifbosidagi ikkita so'zdan iborat bo'lishi va ikkalasi ham bosh harf bilan boshlanishi kerak. Noto'g'ri qiymatlar istisno qilishi, uni har qanday usulda boshqarishi, tegishli xato kodini va xato xabarini chop etishi kerak: Tasdiqlash yo'q. Va bularning barchasini Lombok kutubxonasidan foydalanmasdan amalga oshiring, uni loyihaga bog'liqlik sifatida kiritmang 😅
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION