JavaRush /בלוג Java /Random-HE /טיפול חריג בבקרי אתחול קפיץ
Павел
רָמָה

טיפול חריג בבקרי אתחול קפיץ

פורסם בקבוצה
תוכן מחזור המאמר שלום שוב! הגיע הזמן לנקות את האבק מהמקלדת. צור פרויקט מגף קפיץ. מהתלות במאבן אנחנו צריכים:
<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;
    }
}
ועכשיו, אני אעשה טריק עם האוזניים ואתן את רשות הדיבור לאלכסיי קוטפוב, במאמרו Exception Handling in Spring Controllers, הוא יגיד לנו איך למלא את הקבצים האלה בתוכן הנכון. קרא לאט, העתק בזהירות את כל הדוגמאות לפרויקט שלך, הרץ ובדוק ב-Postman. אם במאמר של אלכסיי השורה הבאה העלתה עבורך שאלות: מייצר = APPLICATION_JSON_VALUE , אז דע שאין לזה שום קשר לטיפול בחריגים, זה אומר שכברירת מחדל כל השיטות של הבקר הזה יחזירו JSON. במידת הצורך, בשיטה ספציפית, ניתן לעקוף את הערך הזה ל- MediaType אחר. אם קראת אותו, המשך הלאה. המאמר לעיל דן באפשרויות שונות למטפלים. הגמיש מביניהם: @ControllerAdvice - מאפשר לך לשנות גם את הקוד וגם את גוף התגובה הסטנדרטית במקרה של שגיאה. בנוסף, זה מאפשר לך לטפל במספר חריגים בבת אחת בשיטה אחת. אבל זה לא הכל, אם תקראו עוד, תקבלו את @ControllerAdvice המשופר לחלוטין בחינם. בוא נעשה קצת עבודת הכנה: אני רוצה שהתגובה תציג הודעות שגיאה מותאמות אישית וסטנדרטיות כאחד. לשם כך, בואו נעשה שינוי במחלקה Response : הוסף שדה אחד נוסף
private String debugMessage;
בואו ניצור בנאי נוסף:
public Response(String message, String debugMessage) {
    this.message = message;
    this.debugMessage = debugMessage;
}
ואל תשכחו ליצור גטר וסטטר לתחום החדש. עכשיו לעניין. בוא נכתוב בקר אחר:
@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 ואחרים. מחלקה זו מטפלת בשגיאות. יש לו חבורה של שיטות, ששמותיהן מבוססות על העיקרון handle + name exception. אם אנחנו רוצים לטפל בחריג בסיסי כלשהו, ​​אז אנחנו יורשים מהמחלקה הזו ונדרוס את השיטה הרצויה . בוא נסיים את שיעור הייעוץ המוגדר כברירת מחדל
@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 (Bad Request) והגוף:
{
    "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 Framework אימות נתונים ב-Spring Boot סיימנו עם התיאוריה להיום. להדרכה, אני מציע את המשימה הבאה: עליך ליישם את אפליקציית NightclubBouncer. דרישות: 1) על האפליקציה לקבל JSON כקלט ולכתוב למסד הנתונים. דוגמה JSON:
{
    "name": "Katy Perry"
    “status”:super star”
}
וגוף התגובה צריך להכיל את הכיתוב הבא: ברוך הבא + שם ! 2) על האפליקציה ליישם את השיטות הבאות: - פלטת רשומה לפי id ממסד הנתונים ללקוח (Postman). - מחיקת רשומה לפי שדה: שם . 3) יש ליישם מיפוי משכבת ​​dto לישות ובחזרה . 4) האפליקציה חייבת לזרוק שגיאת KickInTheAssException (עליך לפתח אותה בעצמך) אם שדה הסטטוס ב-JSON הנכנס אינו שווה ל: super star 5) שגיאת KickInTheAssException חייבת להיות מטופלת על ידי ControllerAdvice , וגוף התגובה חייב להכיל את הודעה: "אל תיתן לי לראות אותך כאן שוב! סטטוס התגובה צריך להיות 400. 6) שגיאה סטנדרטית EntityNotFoundException , שמתרחשת, למשל, אם רק קייטי פרי הגיעה למועדון ושמרה במסד הנתונים עם id = 1 , ואתה קראת לשיטת "תצוגה רשומה לפי id" ורצית כדי להציג את הרשומה עם id = 2 , שאינה במסד הנתונים. שגיאה זו חייבת להיות מטופלת על ידי שיטה שנעקה על המחלקה ResponseEntityExceptionHandler , שאחת מהן תלויה בך כדי להבין בעצמך. על התגובה להיות בסטטוס המתאים. 7) בצע את האימות: אפשרות פשוטה - אסור לשדות ה-JSON להיות null, או יותר קשה, השדה "שם" חייב להיות מורכב משתי מילים מהאלפבית הלטיני ושניהם חייבים להתחיל באות גדולה. ערכים לא חוקיים צריכים לזרוק חריג, לטפל בו בכל דרך, להדפיס את קוד השגיאה המתאים והודעת שגיאה: לא לאמת. והטמיע את כל זה מבלי להשתמש בספריית Lombok, אל תכלול את זה כתלות בפרויקט 😅
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION