عندما نقوم بتطوير تطبيقات الويب الربيعية ، للتحقق من استثناءات مثل IOException و ClassNotFoundException ، فإن المترجم غالبًا ما يطالب المبرمج باستخدام try-catch لالتقاط صريح. للحصول على استثناءات غير محددة مثل ClassCastException و NullPointerException ، لن يطالبك المترجم ، وهو في كثير من الأحيان جانبًا يعكس قدرة كتابة رمز المبرمج.
في Spring Web ، وخاصة تطبيقات Boot Spring ، عندما يتم استدعاء الطلب بنجاح ، فإنه سيعيد عمومًا كائنًا بتنسيق json ، كما هو موضح في الشكل أدناه:
ولكن ماذا لو كان الطلب يلقي بمثابة RuntimeException ؟ إذا لم نفعل المعالجة ، فستظهر الصفحة التالية عندما ندعو مرة أخرى:
وهذا يعني ، عند حدوث خطأ في المكالمة ، ستقوم Boot Spring-Boot بتخطيط الطلب إلى مسار /error افتراضيًا. إذا لم يكن هناك معالج طلب المسار المقابل ، فسوف يعود إلى صفحة خطأ Whitelabel أعلاه.
1. تخصيص صفحة معالجة الأخطاء
بالطبع ، من المستحيل عدم معالجة استثناءات وقت التشغيل! الممارسة المعتادة هي تخصيص صفحة الخطأ الموحدة ثم العودة. وفقًا للفكرة أعلاه ، نقوم بتنفيذ وحدة تحكم مع مسار طلب /error . تقوم وحدة التحكم بإرجاع عنوان مسار المورد ، ويحدد وحدة تحكم باستخدام مسار خريطة طلب /error وتنفيذ واجهة ErrorController . الرمز كما يلي:
MyErrorPageController
حزمة com.example.demo.controller.handler.errorpage ؛ استيراد org.springframework.boot.web.servlet.errorController myerrorpageController. * * الوصف: صفحة خطأ مخصصة * * @Author: Huangjiawei * since: 13 يونيو ، 2018 * version: $ revision $ date $ $ lastChangedBy $ * */ @controlpublic class myerrorpageController تنفذ errordcontroller { @requestmapping ("/error") // يقع هذا المورد في الدليل الموارد/الثابت} Override Public String geterRorpath () {return null ؛ }} ثم قم بإنشاء ملف error.html في الدليل reosurces/static :
<! doctype html> <html> <head> <meta charset = "utf-8"> <title> إدراج العنوان هنا </title> </head> <body> <h1> هذه صفحة خطأ! مخزنة في الموارد/الدليل الثابت. المكالمة الافتراضية موجودة في خطأ الربيع </h1> </body> </html>
طلب http://localhost:7000/demo/getUserInfoWithNoHandler.json مرة أخرى ، على النحو التالي:
@ControllerAdvice و @ResponseBody و @ExceptionHandler للتعامل مع الاستثناءات بشكل موحد
في الربيع ، يمكن استخدام التعليقات التوضيحية الثلاثة أعلاه لمعالجة الاستثناءات الموحدة. بشكل افتراضي ، يمكننا تحديد معالج المعالج الموحد لأنواع معينة من الاستثناءات التي تظهر في النظام. على سبيل المثال ، إذا كان النظام يلقي NullPointerException ، فيمكننا تحديد معالج خصيصًا لـ NullPointerException . الرمز كما يلي:
واجهة getUserInfoWithNullPointerException
/** * اختبار معالجة أخطاء المؤشر الفارغ * return * throws nullpointerxception */ @requestmapping (value = "getUserInFowithNullPointerException.json" ، method = requestMethod.get) الطالب العام getUserInFowithNullPointerxception () throwsceception
NullPointerExceptionHandler.java
package com.example.demo.controller.handler ؛ استيراد org.springframework.web.bind.annotation.controlleradvice ؛ استيراد org.springframework.web.bind.annotation.exceptionhandler ؛ استيراد org.springframework.web com.example.demo.pojo.errorret ؛/** * * الفئة nullpointerexceptionHandler. * * الوصف: معالجة مؤشرات فارغة * * @author: huangjiawei * since: 13 يونيو 2018 * version: $ revision $ $ $ $ lastChangedby $ */ @ @controlervicpublicpublicpublic nullpointerexceptionler { @exceptionhandler (nullpointerxception.classe) E.PrintStackTrace () ؛ خطأ errorreturn = errorreturn () جديد ؛ error.setReturnCode ("-1") ؛ error.setdesc ("حدث استثناء مؤشر فارغ!") ؛ عودة الخطأ ؛ }} تنفيذ المتصفح: http://localhost:7000/demo/getUserInfoWithNullPointerException.json
وعلى نفس المنوال ، إذا كنا بحاجة إلى توفير معالج موحد لاستثناءات وقت التشغيل الأخرى ، فيمكننا أيضًا تحديد معالج لكل نوع استثناء أعلاه. على سبيل المثال ، إذا كنا نريد تحديد معالج لـ ArithmeticException ، فسنحتاج فقط إلى إنشاء فئة أو طريقة ، ثم إضافة ArithmeticException.class إلى @ExceptionHanler enootation على الطريقة لتحديد نوع الاستثناء.
ومع ذلك ، هل وجدت أن بهذه الطريقة ، تحدد فئة معالجة الاستثناء أو طريقة لكل نوع استثناء. نظرًا لوجود العديد من أنواع الاستثناءات في وقت التشغيل ، فمن المستحيل تحديد فئة أو طريقة معالج لكل نوع. في هذه الحالة ، يمكن لـ Spring أيضًا حلها. إذا لم نحدد معالجًا لنوع معين من الاستثناءات ، مثل ArithmeticException ، فيمكننا تحديد Exception أو معالج Throwable للتعامل معه بشكل موحد.
ميزة القيام بذلك هي أنه يقلل من عدد فئات المعالجات ونقل الاستثناءات مع التعامل مع فئة الوالدين ، والتي تعد أيضًا ميزة كبيرة للميراث! ومع ذلك ، عندما تحدد معالجًا لنوع معين من الاستثناء Exception في نفس الوقت ، كن حذرًا ، لا توجد بالضرورة علاقة ذات أولوية هنا ، أي أنه قد لا يحدث بالضرورة أن يتم تنفيذ معالج استثناء الوالدين فقط. قد يقوم فقط بتنفيذ المعالج A ، وليس فقط معالج B ، أو المعالج B فقط ، وليس المعالج A. على سبيل المثال ، سيتم تمرير استثناء NullPointerExceptionHandler إلى Exception (ولكن لن يتم تمرير ArithmeticException إلى Exception )
لنفترض الآن أننا نحدد كل من NullPointerExceptionHandler أعلاه ExceptionThrowableHandler أدناه. ثم عند حدوث NullPointerException ، سيتم تنفيذ طريقة ExceptionThrowableHandler افتراضيًا.
ExceptionThrowableHandler.java
package com.example.demo.controller.handler ؛ استيراد org.springframework.web.bind.annotation.controlleradvice ؛ استيراد org.springframework.web.bind.annotation.exceptionhandler ؛ استيراد org.springframework.web com.example.demo.pojo.errorret ؛/** * * فئة الاستثناء القابلة للاستثمار. * * الوصف: يتم تمرير بعض الاستثناءات إلى استثناءات عالية المستوى (ولكن لن يتم إرسال ArithMeticeSception إلى استثناء) * * Author: Huangjiawei * since: 13 يونيو ، 2018 * version: $ revision $ date $ $ lastChangedby $ * dealthRowable () {errorreturn error = new Errorreturn () ؛ خطأ. error.setReturnCode ("-1") ؛ عودة الخطأ ؛ } exceptionHandler (استثناء error.setReturnCode ("-1") ؛ error.setdesc ("معالجة الاستثناء العام!") ؛ عودة الخطأ ؛ }} تنفيذ المتصفح: http://localhost:7000/demo/getUserInfoWithNullPointerException.json
يمكن العثور على أن المعالج الذي ينفذ Exception فقط ولكنه لا ينفذ مؤشرًا فارغًا ، أي أن معالجة الاستثناء يتم إرسالها للأعلى. دعونا نلقي نظرة على الموقف الذي يتم فيه إلقاء ArithmeticException :
getUserInfoWithArithmeticException.json
/** * اختبار معالجة أخطاء المؤشر الفارغ * return * throws nullpointerxception */ @requestmapping (value = "getUserInFowithArithMithEmpection.json" ، method = requestMethod.get) الطالب العام getUserInFowithArithMeticexception
ArithmeticExceptionHandler.java
package com.example.demo.controller.handler ؛ استيراد org.springframework.web.bind.annotation.controlleradvice ؛ استيراد org.springframework.web.bind.annotation.exceptionhandler ؛ استيراد org.springframework.web com.example.demo.pojo.errorreturn ؛ controlleradvicepublic class ArithMeticexceptionHandler { / *** التعامل مع ArithMeticexceptionException استثناء* @RERSPONSEBONDERNEXCENEDLER (ARITHMETICEXCESTION.CLASS) ERRORRETURNURN PublicArtiTeCexte () erroroBject.setReturnCode ("-1") ؛ erroroBject.setdesc ("حدث استثناء في المعالجة الحسابية!") ؛ إرجاع errorObject ؛ }} تنفيذ المتصفح: http://localhost:7000/demo/getUserInfoWithArithmeticException.json
نتيجة لذلك ، وجد أن معالجة الاستثناء لم يتم نقلها إلى ExceptionHandler في الطابق العلوي.
ملخص: كن حذرًا بشكل خاص عند تحديد المعالجات من كلا النوعين المحددين وأنواع الوالدين مثل Exception . لن تتم معالجة كل الاستثناءات في المستوى العلوي. إذا كنا نريد فقط تقليل عدد فئات المعالجات ولا نرغب في إضافة فئات أو طرق لكل نوع محدد من المعالجات ، فإن المحرر يوصي باستخدام instanceof الرئيسية لمثلة الحكم على نوع الاستثناء.
كما هو الحال في الكود التالي ، نقوم فقط بإنشاء معالج استثناء عام ، ونتعامل مع استثناءات Exception ، ونستخدم instanceof لإصدار الأحكام.
exceptionHandler (استثناء // هنا يمكنك استخدام eastyof لتحديد نوع الاستثناء if (e extuteof arithMeticexception) {error.setReturnCode ("-1") ؛ error.setDesc ("ArithMeticexception Handling!") ؛ عودة الخطأ ؛ } system.err.println ("استثناء") ؛ error.setReturnCode ("-1") ؛ error.setdesc ("معالجة الاستثناء العام!") ؛ عودة خطأ ؛} يقوم المتصفح بتنفيذ الواجهة التي ترمي ArithmeticException ، على النحو التالي:
عنوان رمز هذه المقالة: https://github.com/smallercoder/spring_exceptionhandler
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.