JavaRush /وبلاگ جاوا /Random-FA /رسیدگی به استثناء در کنترلرهای بوت فنری
Павел
مرحله

رسیدگی به استثناء در کنترلرهای بوت فنری

در گروه منتشر شد
محتویات چرخه مقاله سلام مجدد! وقت آن است که گرد و غبار صفحه کلید خود را پاک کنید. یک پروژه بهار بوت ایجاد کنید. از وابستگی های maven ما نیاز داریم:
<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>
قبل از مطالعه بیشتر، یک ساختار پروژه ایجاد کنید: رسیدگی به استثناء در کنترلرهای بوت فنری - 1 BusinessException و CustomException:
public class BusinessException extends Exception{
    public BusinessException(String message) {
        super(message);
    }
}

public class CustomException extends Exception{
    public CustomException(String message) {
        super(message);
    }
}
و کلاس Response
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;
    }
}
و اکنون، من یک ترفند با گوش هایم انجام می دهم و به الکسی کوتپوف می دهم، در مقاله خود Exception Handling in Spring Controller، او به ما می گوید که چگونه این فایل ها را با محتوای صحیح پر کنیم. آهسته بخوانید، تمام نمونه ها را با دقت در پروژه خود کپی کنید، اجرا کنید و در Postman تست کنید. اگر در مقاله الکسی خط زیر برای شما سوالاتی ایجاد کرد: produces = APPLICATION_JSON_VALUE ، پس بدانید که ربطی به مدیریت استثنا ندارد، می گوید که به طور پیش فرض همه متدهای این کنترلر JSON را برمی گرداند. در صورت لزوم، در یک روش خاص، می توان این مقدار را به یک MediaType دیگر رد کرد، اگر آن را خوانده اید، ادامه دهید. در مقاله بالا گزینه‌های مختلف برای هندلرها بحث شده است. انعطاف پذیرترین آنها: @ControllerAdvice - به شما امکان می دهد در صورت بروز خطا، کد و بدنه پاسخ استاندارد را تغییر دهید. علاوه بر این، به شما امکان می دهد چندین استثنا را به طور همزمان در یک روش مدیریت کنید. اما این همه چیز نیست، اگر بیشتر بخوانید، @ControllerAdvice بهبود یافته را کاملاً رایگان دریافت خواهید کرد. بیایید چند کار مقدماتی انجام دهیم: من می‌خواهم پاسخ پیام‌های خطای سفارشی و استاندارد را نمایش دهد. برای انجام این کار، اجازه دهید تغییری در کلاس Response ایجاد کنیم : یک فیلد دیگر اضافه کنید
private String debugMessage;
بیایید یک سازنده اضافی ایجاد کنیم:
public Response(String message, String debugMessage) {
    this.message = message;
    this.debugMessage = debugMessage;
}
و فراموش نکنید که یک Getter و Setter برای فیلد جدید ایجاد کنید. حالا سر اصل مطلب. بیایید یک کنترلر دیگر بنویسیم:
@RestController
public class Example7Controller {
    @GetMapping(value = "/testExtendsControllerAdvice")
    public ResponseEntity<?> testExtendsControllerAdvice(@RequestBody Response response) {
        return  ResponseEntity.ok(response);
    }
}
بیایید در پستچی تست کنیم: JSON را به http://localhost:8080/testExtendsControllerAdvice ارسال کنید
{
    "message": "message"
}
در پاسخ ما یک وضعیت 200 و یک بدن دریافت خواهیم کرد
{
    "message": "message",
    "debugMessage": null
}
اکنون JSON آشکارا نادرست را ارسال خواهیم کرد
{
    11"message": "message"
}
در پاسخ، وضعیت 400 را دریافت می کنیم (اگر فراموش کرده اید معنی آن چیست، آن را در اینترنت جستجو کنید) و یک بدنه پاسخ خالی. البته هیچکس از این راضی نیست، بیایید با آن مبارزه کنیم. قبلاً، @ControllerAdvice را از ابتدا ایجاد کردیم ، اما در Spring Boot یک الگو وجود دارد - ResponseEntityExceptionHandler . در حال حاضر بسیاری از استثناها را کنترل می کند، به عنوان مثال: NoHandlerFoundException ، HttpMessageNotReadableException ، MethodArgumentNotValidException و موارد دیگر. این کلاس خطاها را کنترل می کند. مجموعه ای از متدها دارد که نام آنها بر اساس دسته اصلی + نام استثنا است. اگر بخواهیم استثناهای اساسی را مدیریت کنیم، از این کلاس ارث می بریم و متد مورد نظر را لغو می کنیم . بیایید کلاس مشاوره پیش فرض را نهایی کنیم
@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);
    }
}
همانطور که متوجه شدید، کنترل کننده مسئول HttpMessageNotReadableException لغو شده است . این استثنا زمانی اتفاق می‌افتد که بدنه درخواستی که به روش کنترلر می‌آید قابل خواندن نباشد - به عنوان مثال، JSON نادرست. متد handleHttpMessageNotReadable () مسئول این استثناست . بیایید دوباره با JSON نادرست درخواستی ارسال کنیم: http://localhost:8080/testExtendsControllerAdvice
{
    11"message": "message"
}
ما پاسخی با کد 400 (درخواست بد) دریافت می کنیم و بدنه:
{
    "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]"
}
اکنون پاسخ نه تنها حاوی کد صحیح، بلکه بدنه ای با پیام های آموزنده است. بیایید بررسی کنیم که چگونه با درخواست JSON صحیح کار می کند:
{
    "message": "message"
}
جواب گرفتیم:
{
    "message": "message",
    "debugMessage": null
}
صادقانه بگویم، من دوست ندارم که پاسخ حاوی فیلدی با مقدار null باشد ، اکنون به سرعت آن را برطرف خواهیم کرد. به کلاس Response بروید و روی فیلد مورد نیاز یک حاشیه قرار دهید
@JsonInclude(JsonInclude.Include.NON_NULL)
private String debugMessage;
پروژه را دوباره راه اندازی می کنیم، درخواست قبلی را دوباره انجام می دهیم و در پاسخ دریافت می کنیم:
{
    "message": "message"
}
با تشکر از حاشیه‌نویسی @JsonInclude(JsonInclude.Include.NON_NULL) ، این قسمت فقط در صورتی در پاسخ گنجانده می‌شود که آن را مشخص کنیم. @JsonInclude در کتابخانه حاشیه نویسی جکسون گنجانده شده است ، دانستن اینکه چه کاری می تواند انجام دهد بسیار مفید است. در اینجا دو مقاله برای انتخاب وجود دارد: حاشیه نویسی جکسون. نویسنده ترجمه کرده است، اما ترجمه را کامل نکرده است ؛ Google Translit کار بسیار خوبی انجام می دهد. اعتبار سنجی لازم است این مبحث با مفهومی مانند اعتبار سنجی تکمیل شود. به عبارت ساده، این یک بررسی است که شی همان شیئی است که ما انتظار داریم. به عنوان مثال: اگر در برنامه "دایرکتوری تلفن" نیاز به بررسی وجود شماره تلفن در پایگاه داده داشته باشیم، قبل از ورود به پایگاه داده، منطقی است که بررسی کنیم آیا کاربر به جای اعداد، حروف را وارد کرده است یا خیر. سه مقاله در مورد اعتبار سنجی، با افزایش پیچیدگی: اعتبار سنجی لوبیاها در بهار تنظیم اعتبار DTO در چارچوب Spring اعتبار سنجی داده ها در Spring Boot ما با تئوری امروز به پایان رسیدیم. برای آموزش، کار زیر را پیشنهاد می کنم: شما باید برنامه NightclubBouncer را پیاده سازی کنید. الزامات: 1) برنامه باید JSON را به عنوان ورودی بپذیرد و در پایگاه داده بنویسد. مثال JSON:
{
    "name": "Katy Perry"
    “status”:super star”
}
و بدنه پاسخ باید حاوی نوشته زیر باشد: خوش آمدید + نام ! 2) برنامه باید روش های زیر را پیاده سازی کند: - خروجی یک رکورد با شناسه از پایگاه داده به مشتری (پستمن). - حذف یک رکورد بر اساس فیلد: نام . 3) نگاشت از لایه dto به موجودیت و back باید پیاده سازی شود . 4) اگر فیلد وضعیت در JSON ورودی برابر نیست ، برنامه باید یک خطای KickInTheAssException ایجاد کند (شما باید خودتان آن را توسعه دهید) اگر فیلد وضعیت در JSON ورودی برابر نیست: فوق ستاره 5) خطای KickInTheAssException باید توسط ControllerAdvice مدیریت شود و بدنه پاسخ باید حاوی موارد زیر باشد. پیام: «اجازه نده دوباره اینجا ببینمت! وضعیت پاسخ باید 400 باشد. 6) خطای استاندارد EntityNotFoundException ، که مثلاً اگر فقط کیتی پری به کلوب بیاید و با id = 1 در پایگاه داده ذخیره شود ، رخ می دهد و شما متد "نمایش رکورد با شناسه" را فراخوانی کرده و می خواهید. برای نمایش رکورد با id = 2 که در پایگاه داده نیست. این خطا باید توسط یک روش لغو شده از کلاس ResponseEntityExceptionHandler کنترل شود ، که تشخیص آن به عهده شماست. پاسخ باید وضعیت مناسبی داشته باشد. 7) اعتبار سنجی را انجام دهید: یک گزینه ساده - فیلدهای JSON نباید پوچ یا دشوارتر باشند، قسمت "نام" باید از دو کلمه الفبای لاتین تشکیل شده باشد و هر دو باید با یک حرف بزرگ شروع شوند. مقادیر نامعتبر باید یک استثنا ایجاد کنند، آن را به هر نحوی مدیریت کنند، کد خطای مناسب و پیام خطا را چاپ کنند: اعتبارسنجی وجود ندارد. و همه اینها را بدون استفاده از کتابخانه لومبوک اجرا کنید، آن را به عنوان وابستگی پروژه درج نکنید.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION