JavaRush /مدونة جافا /Random-AR /معالجة الاستثناءات في وحدات تحكم التمهيد الربيعي
Павел
مستوى

معالجة الاستثناءات في وحدات تحكم التمهيد الربيعي

نشرت في المجموعة
محتويات دورة المادة مرحبًا مرة أخرى! حان الوقت لنفض الغبار عن لوحة المفاتيح. إنشاء مشروع التمهيد الربيعي. من التبعيات المخضرمة نحتاج إلى:
<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);
    }
}
وفئة الاستجابة
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;
    }
}
والآن سأقوم بخدعة بأذني وأعطي الكلمة لأليكسي كوتيبوف، في مقالته " معالجة الاستثناءات في أجهزة التحكم الربيعية"، سيخبرنا بكيفية ملء هذه الملفات بالمحتوى الصحيح. اقرأ ببطء، وانسخ جميع الأمثلة بعناية في مشروعك، وقم بتشغيلها واختبارها في Postman. إذا أثار السطر التالي أسئلة لك في مقالة Alexey: Produce = APPLICATION_JSON_VALUE ، فاعلم أنه لا علاقة له بمعالجة الاستثناءات، فهو يشير إلى أن جميع أساليب وحدة التحكم هذه ستعيد JSON بشكل افتراضي. إذا لزم الأمر، وبطريقة معينة، يمكن تجاوز هذه القيمة إلى MediaType آخر. إذا كنت قد قرأتها، فانتقل. تتناول المقالة أعلاه الخيارات المختلفة للمعالجات. الأكثر مرونة منها: @ControllerAdvice - فهو يسمح لك بتغيير كل من الكود ونص الاستجابة القياسية في حالة حدوث خطأ. بالإضافة إلى ذلك، فهو يسمح لك بمعالجة استثناءات متعددة مرة واحدة بطريقة واحدة. ولكن هذا ليس كل شيء، إذا قرأت المزيد، فستحصل على @ControllerAdvice المحسّن مجانًا تمامًا . لنقم ببعض الأعمال التحضيرية: أريد أن تعرض الاستجابة رسائل الخطأ المخصصة والقياسية. للقيام بذلك، دعونا نجري تغييرًا على فئة الاستجابة : أضف حقلًا آخر
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 ، وسنقوم بإصلاح ذلك بسرعة الآن. انتقل إلى فئة الاستجابة وقم بوضع تعليق توضيحي على الحقل المطلوب
@JsonInclude(JsonInclude.Include.NON_NULL)
private String debugMessage;
نعيد تشغيل المشروع، ونقدم الطلب السابق مرة أخرى، وفي الرد نحصل على:
{
    "message": "message"
}
بفضل التعليق التوضيحي @JsonInclude(JsonInclude.Include.NON_NULL) ، لن يتم تضمين هذا الحقل في الاستجابة إلا إذا قمنا بتحديده. تم تضمين @JsonInclude في مكتبة جاكسون للتعليقات التوضيحية ، ومن المفيد جدًا معرفة ما يمكنه فعله. فيما يلي مقالتان للاختيار من بينهما: تعليقات جاكسون التوضيحية. قام المؤلف بالترجمة، لكنه لم يكمل الترجمة ؛ يقوم Google Translit بعمل رائع. التحقق من الصحة من الضروري استكمال هذا الموضوع بمفهوم مثل التحقق من الصحة. ببساطة، هذا هو التحقق من أن الكائن هو الكائن الذي نتوقعه. على سبيل المثال: إذا كنا بحاجة في تطبيق "دليل الهاتف" إلى التحقق من وجود أرقام الهواتف في قاعدة البيانات، فمن المنطقي قبل الدخول إلى قاعدة البيانات التحقق مما إذا كان المستخدم قد أدخل أحرفًا بدلاً من الأرقام. ثلاث مقالات حول التحقق من الصحة، في تعقيد متزايد: التحقق من صحة Bean في Spring إعداد التحقق من صحة DTO في Spring Framework التحقق من صحة البيانات في Spring Boot لقد انتهينا من النظرية لهذا اليوم. للتدريب أقترح المهمة التالية: تحتاج إلى تنفيذ تطبيق NightclubBouncer. المتطلبات: 1) يجب أن يقبل التطبيق JSON كمدخل ويكتب في قاعدة البيانات. مثال جيسون:
{
    "name": "Katy Perry"
    “status”:super star”
}
ويجب أن يحتوي نص الرد على النقش التالي: مرحبًا + اسم ! 2) يجب على التطبيق تنفيذ الطرق التالية: - إخراج سجل بالمعرف من قاعدة البيانات إلى العميل (Postman). - حذف سجل حسب الحقل: الاسم . 3) يجب تنفيذ التعيين من طبقة dto إلى الكيان والعودة . 4) يجب أن يلقي التطبيق خطأ KickInTheAssException (تحتاج إلى تطويره بنفسك) إذا كان حقل الحالة في JSON الوارد لا يساوي: super star 5) يجب معالجة خطأ KickInTheAssException بواسطة ControllerAdvice ، ويجب أن يحتوي نص الاستجابة على الرسالة: "لا تدعني أراك هنا مرة أخرى! يجب أن تكون حالة الاستجابة 400. 6) الخطأ القياسي EntityNotFoundException ، والذي يحدث، على سبيل المثال، إذا جاءت Katy Perry فقط إلى النادي وحفظتها في قاعدة البيانات بالمعرف = 1 ، وقمت باستدعاء طريقة "عرض السجل حسب المعرف" وأردت لعرض السجل بالمعرف = 2 ، وهو غير موجود في قاعدة البيانات. يجب معالجة هذا الخطأ من خلال طريقة متجاوزة من فئة ResponseEntityExceptionHandler ، أي منها متروك لك لاكتشافه بنفسك. يجب أن يكون الرد بالحالة المناسبة. 7) قم بالتحقق من الصحة: ​​خيار بسيط - يجب ألا تكون حقول JSON فارغة، أو أكثر صعوبة، ويجب أن يتكون حقل "الاسم" من كلمتين من الأبجدية اللاتينية ويجب أن يبدأ كلاهما بحرف كبير. يجب أن تطرح القيم غير الصالحة استثناءً، وتتعامل معه بأي شكل من الأشكال، وتطبع رمز الخطأ المناسب ورسالة الخطأ: لا يوجد التحقق من الصحة. وقم بتنفيذ كل هذا دون استخدام مكتبة لومبوك، ولا تقم بإدراجها كتبعية للمشروع 😅
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION