เมื่อเราพัฒนาแอปพลิเคชั่นเว็บฤดูใบไม้ผลิเพื่อตรวจสอบข้อยกเว้นเช่น IOException และ ClassNotFoundException คอมไพเลอร์มักจะแจ้งให้โปรแกรมเมอร์ใช้ try-catch เพื่อจับภาพที่ชัดเจน สำหรับข้อยกเว้นที่ไม่ได้ตรวจสอบเช่น ClassCastException และ NullPointerException คอมไพเลอร์จะไม่แจ้งให้คุณทราบซึ่งมักจะเป็นแง่มุมที่สะท้อนถึงความสามารถในการเขียนโค้ดของโปรแกรมเมอร์
ใน Spring Web โดยเฉพาะแอปพลิเคชันฤดูใบไม้ผลิที่เรียกว่าคำขอสำเร็จโดยทั่วไปจะส่งคืนวัตถุในรูปแบบ json ดังแสดงในรูปด้านล่าง:
แต่ถ้าคำขอพุ่งเข้าหา RuntimeException ? หากเราไม่ทำการประมวลผลหน้าต่อไปนี้จะปรากฏขึ้นเมื่อเราโทรอีกครั้ง:
กล่าวคือเมื่อมีข้อผิดพลาดเกิดขึ้นในการโทรสปริงบู๊ทจะแมปคำขอไปยังเส้นทาง /error โดยค่าเริ่มต้น หากไม่มีโปรเซสเซอร์คำขอพา ธ ที่สอดคล้องกันจะกลับไปที่หน้าข้อผิดพลาด Whitelabel ด้านบน
1. ปรับแต่งหน้าการจัดการข้อผิดพลาด
แน่นอนว่าเป็นไปไม่ได้ที่จะไม่ดำเนินการยกเว้นรันไทม์! การปฏิบัติตามปกติคือการปรับแต่งหน้าข้อผิดพลาดแบบครบวงจรแล้วกลับมา ตามแนวคิดข้างต้นเราใช้คอนโทรลเลอร์ด้วยเส้นทางการร้องขอของ /error คอนโทรลเลอร์ส่งคืนที่อยู่พา ธ ทรัพยากรกำหนดคอนโทรลเลอร์ด้วยเส้นทางแผนที่คำขอของ /error และดำเนินการอินเตอร์เฟส ErrorController รหัสมีดังนี้:
MyErrorPageController
แพ็คเกจ com.example.demo.controller.handler.errorpage; นำเข้า org.springframework.boot.web.servlet.error.errorcontroller; นำเข้า org.springframework.stereotype.controller; Myerrorpagecontroller * * คำอธิบาย: หน้าข้อผิดพลาดที่กำหนดเอง * * @author: Huangjiawei * @since: 13 มิถุนายน 2018 * @version: $ revision $ $ date $ $ lastChangedBy $ * */ @controllerPublic คลาส MyerRorPageController // ทรัพยากรนี้อยู่ในทรัพยากร/ไดเรกทอรีแบบคงที่} @Override สตริงสาธารณะ getERRORRORPATH () {return null; - จากนั้นสร้าง error.html ไฟล์ 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
/** * ทดสอบการจัดการข้อผิดพลาดตัวชี้ null * @return * @throws nullpointerexception */ @requestmapping (value = "getUserInfowithNullPoInterexception.json", method = requestMethod.get)
NullPointerExceptionHandler.java
แพ็คเกจ com.example.demo.controller.handler; นำเข้า org.springframework.web.bind.annotation.controlleradvice; นำเข้า org.springframework.web.bind.annotation.exceptionhandler; com.example.demo.pojo.errorreturn;/** * * คลาส nullpointerexceptionhandler * * คำอธิบาย: จัดการตัวชี้ null * * @author: Huangjiawei * @since: 13 มิถุนายน 2018 * @version: $ revision $ $ date $ $ lastChangedBy $ */ @controllerAdvicePublic คลาส nullpoInterexceptionhandler E.PrintStackTrace (); ข้อผิดพลาด errorreturn = new errorreturn (); Error.setReturnCode ("-1"); ERROR.SETDESC ("ข้อยกเว้นตัวชี้ NULL เกิดขึ้น!"); เกิดข้อผิดพลาดคืน; - การดำเนินการเบราว์เซอร์: http://localhost:7000/demo/getUserInfoWithNullPointerException.json
ในทำนองเดียวกันหากเราต้องการจัดทำโปรเซสเซอร์แบบครบวงจรสำหรับข้อยกเว้นรันไทม์อื่น ๆ เรายังสามารถกำหนดโปรเซสเซอร์สำหรับแต่ละประเภทข้อยกเว้นดังกล่าวข้างต้น ตัวอย่างเช่นหากเราต้องการกำหนดโปรเซสเซอร์สำหรับ ArithmeticException เราต้องสร้างคลาสหรือวิธีการจากนั้นเพิ่ม ArithmeticException.class ไปยัง @ExceptionHanler Annotation บนวิธีการเพื่อระบุประเภทข้อยกเว้น
อย่างไรก็ตามคุณพบว่าด้วยวิธีนี้กำหนดคลาสการจัดการข้อยกเว้นหรือวิธีการสำหรับแต่ละประเภทข้อยกเว้น เนื่องจากมีข้อยกเว้นมากมายที่รันไทม์จึงเป็นไปไม่ได้ที่จะระบุคลาสโปรเซสเซอร์หรือวิธีการสำหรับแต่ละประเภท ในกรณีนี้ฤดูใบไม้ผลิยังสามารถแก้ปัญหาได้ หากเราไม่ได้กำหนดโปรเซสเซอร์สำหรับข้อยกเว้นบางประเภทเช่น ArithmeticException เราสามารถกำหนด Exception หรือโปรเซสเซอร์ Throwable เพื่อจัดการอย่างสม่ำเสมอ
ข้อได้เปรียบของการทำเช่นนี้คือลดจำนวนคลาสโปรเซสเซอร์และการถ่ายโอนการจัดการข้อยกเว้นไปยังคลาสหลักซึ่งเป็นข้อได้เปรียบที่สำคัญของการสืบทอด! อย่างไรก็ตามเมื่อคุณกำหนดโปรเซสเซอร์ของข้อยกเว้นประเภทเฉพาะและ Exception ในเวลาเดียวกันโปรดระวังไม่จำเป็นต้องมีความสัมพันธ์ลำดับความสำคัญที่นี่นั่นคือมันอาจไม่เกิดขึ้น มันอาจดำเนินการโปรเซสเซอร์ A ไม่เพียง แต่โปรเซสเซอร์ B หรือเฉพาะโปรเซสเซอร์ B ไม่ใช่โปรเซสเซอร์ A ตัวอย่างเช่นข้อยกเว้น NullPointerExceptionHandler จะถูกส่งผ่านไปยัง Exception (แต่ ArithmeticException จะไม่ถูกส่งผ่านไปยัง Exception )
ตอนนี้สมมติว่าเรากำหนดทั้ง NullPointerExceptionHandler ด้านบนและ ExceptionThrowableHandler ด้านล่าง จากนั้นเมื่อมีการ NullPointerException วิธีการ ExceptionThrowableHandler จะถูกดำเนินการตามค่าเริ่มต้น
ExceptionThrowableHandler.java
แพ็คเกจ com.example.demo.controller.handler; นำเข้า org.springframework.web.bind.annotation.controlleradvice; นำเข้า org.springframework.web.bind.annotation.exceptionhandler; com.example.demo.pojo.errorreturn;/** * * คลาส ExceptionThrowableHandler * * คำอธิบาย: ข้อยกเว้นบางอย่างถูกส่งผ่านไปยังข้อยกเว้นระดับสูง (แต่ arithmeticexception จะไม่ถูกส่งไปยังข้อยกเว้น) * * @author: Huangjiawei * @since: 13 มิถุนายน 2018 * @version: $ revision $ $ $ $ lastChangedBy $ */ @controlleradvicepublic dealthrowable () {errorreturn error = new errorreturn (); ERROR.SETDESC ("จัดการที่สามารถโยนได้!"); Error.setReturnCode ("-1"); เกิดข้อผิดพลาดคืน; } @ExceptionHandler (Exception.class) @ResponseBody Public Public ErrorRorReRUNCOMMONException () {ข้อผิดพลาด errorReRorn = ใหม่ errorReRorTurn (); Error.setReturnCode ("-1"); ERROR.SETDESC ("การจัดการข้อยกเว้นสาธารณะ!"); เกิดข้อผิดพลาดคืน; - การดำเนินการเบราว์เซอร์: http://localhost:7000/demo/getUserInfoWithNullPointerException.json
จะพบได้ว่าโปรเซสเซอร์ที่ดำเนินการ Exception แต่ไม่ได้ดำเนินการตัวชี้โมฆะนั่นคือการประมวลผลข้อยกเว้นจะถูกส่งขึ้นไป มาดูสถานการณ์ที่ ArithmeticException ถูกโยนลง:
getUserInfoWithArithmeticException.json
/** * ทดสอบการจัดการข้อผิดพลาดตัวชี้ null * @return * @throws nullpointerexception */ @requestmapping (value = "getUserInfowithArithMeticexception.json", method = requestMethod.get)
ArithmeticExceptionHandler.java
แพ็คเกจ com.example.demo.controller.handler; นำเข้า org.springframework.web.bind.annotation.controlleradvice; นำเข้า org.springframework.web.bind.annotation.exceptionhandler; com.example.demo.pojo.errorreturn; @controlleradvicepublic คลาส arithmeticexceptionhandler { / *** จัดการ arithmeticexceptionexception ข้อยกเว้น* @return* / @ResponseBody @ExceptionHandler errorObject.setReturnCode ("-1"); ErrorObject.setDesc ("ข้อยกเว้นเกิดขึ้นในการประมวลผลทางคณิตศาสตร์!"); ส่งคืน errorObject; - การดำเนินการเบราว์เซอร์: http://localhost:7000/demo/getUserInfoWithArithmeticException.json
เป็นผลให้พบว่าการจัดการข้อยกเว้นไม่ได้ส่งไปยัง ExceptionHandler ที่ระดับบน
สรุป: ระมัดระวังเป็นพิเศษเมื่อกำหนดโปรเซสเซอร์ทั้งประเภทเฉพาะและประเภทหลักเช่น Exception ข้อยกเว้นทั้งหมดจะไม่ถูกประมวลผลในระดับบน หากเราต้องการลดจำนวนคลาสโปรเซสเซอร์เท่านั้นและไม่ต้องการเพิ่มคลาสหรือวิธีการสำหรับโปรเซสเซอร์แต่ละประเภทเฉพาะตัวแก้ไขแนะนำให้ใช้คำหลัก instanceof เพื่อตัดสินประเภทข้อยกเว้น
ในรหัสต่อไปนี้เราสร้างตัวจัดการข้อยกเว้นสาธารณะจัดการข้อยกเว้น Exception และใช้ instanceof ของการตัดสิน
@ExceptionHandler (Exception.class) @ResponseBodyPublic ErrorReRorTurn DealCommOnexception (Exception e) {ข้อผิดพลาด errorreturn = new errorReRorReRn (); // ที่นี่คุณสามารถใช้ InstanceOF เพื่อกำหนดประเภทข้อยกเว้นถ้า (e instanceof arithMeticexception) {error.setReturnCode ("-1"); Error.setDesc ("การจัดการ arithmeticexception!"); เกิดข้อผิดพลาดคืน; } system.err.println ("ข้อยกเว้น"); Error.setReturnCode ("-1"); ERROR.SETDESC ("การจัดการข้อยกเว้นสาธารณะ!"); return error;} เบราว์เซอร์ดำเนินการอินเทอร์เฟซที่โยน ArithmeticException ดังนี้:
ที่อยู่รหัสของบทความนี้: https://github.com/smallercoder/spring_exceptionhandler
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น