JavaRush /จาวาบล็อก /Random-TH /การจัดการข้อยกเว้นใน Spring Boot Controllers
Павел
ระดับ

การจัดการข้อยกเว้นใน Spring Boot Controllers

เผยแพร่ในกลุ่ม
เนื้อหาของรอบบทความ สวัสดีอีกครั้ง! ถึงเวลาปัดฝุ่นคีย์บอร์ดของคุณแล้ว สร้างโปรเจ็กต์สปริงบูต จากการพึ่งพา 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>
ก่อนที่จะอ่านเพิ่มเติม ให้สร้างโครงสร้างโครงการ: การจัดการข้อยกเว้นใน Spring Boot Controllers - 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;
    }
}
และตอนนี้ ฉันจะใช้หูของฉันและเล่าให้ Alexey Kutepov ในบทความของเขาException Handling in Spring Controllers เขาจะบอกเราถึงวิธีเติมไฟล์เหล่านี้ด้วยเนื้อหาที่ถูกต้อง อ่านช้าๆ คัดลอกตัวอย่างทั้งหมดลงในโปรเจ็กต์ของคุณอย่างระมัดระวัง รันและทดสอบในบุรุษไปรษณีย์ หากในบทความของ Alexey บรรทัดต่อไปนี้ทำให้เกิดคำถามสำหรับคุณ: ผลิต = 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รวมอยู่ใน ไลบรารีคำอธิบายประกอบ ของ Jacksonมันมีประโยชน์มากที่จะรู้ว่ามันทำอะไรได้บ้าง ต่อไปนี้เป็นบทความสองบทความที่มีให้เลือก: คำอธิบายประกอบของ Jackson ผู้เขียนแปลแล้ว แต่แปลไม่เสร็จ Google Translit ทำงานได้ดีมาก การตรวจสอบความถูก ต้อง มีความจำเป็นต้องเสริมหัวข้อนี้ด้วยแนวคิดเช่นการตรวจสอบความถูกต้อง พูดง่ายๆ ก็คือเป็นการตรวจสอบว่าวัตถุนั้นเป็นวัตถุที่เราคาดหวัง ตัวอย่างเช่น: หากในแอปพลิเคชัน Phone Directory เราจำเป็นต้องตรวจสอบหมายเลขโทรศัพท์ในฐานข้อมูลก่อนเข้าสู่ฐานข้อมูลมีเหตุผลที่จะตรวจสอบว่าผู้ใช้ป้อนตัวอักษรแทนตัวเลขหรือไม่ บทความสามบทความเกี่ยวกับการตรวจสอบความถูกต้องในการเพิ่มความซับซ้อน: การตรวจสอบความถูกต้องของ Bean ใน Spring การตั้งค่าการตรวจสอบความถูกต้องของ DTO ใน การตรวจสอบความถูกต้องของข้อมูล Spring Framework ใน Spring Boot เราเสร็จสิ้นทฤษฎีสำหรับวันนี้แล้ว สำหรับการฝึกอบรม ฉันขอแนะนำงานต่อไปนี้: คุณต้องใช้งานแอปพลิเคชัน NightclubBouncer ข้อกำหนด: 1) แอปพลิเคชันจะต้องยอมรับ JSON เป็นอินพุตและเขียนลงในฐานข้อมูล ตัวอย่าง JSON:
{
    "name": "Katy Perry"
    “status”:super star”
}
และเนื้อหาของการตอบกลับควรมีข้อความต่อไปนี้: Welcome + name ! 2) แอปพลิเคชันจะต้องใช้วิธีการต่อไปนี้: - ส่งออกบันทึกด้วยIDจากฐานข้อมูลไปยังไคลเอนต์ (บุรุษไปรษณีย์) - การลบบันทึกตามฟิลด์: ชื่อ 3) การแมปจากเลเยอร์ dtoไปยังเอนทิตีและด้านหลังจะต้องถูกนำไปใช้ 4) แอปพลิเคชันจะต้องส่ง ข้อผิดพลาด KickInTheAssException (คุณต้องพัฒนาด้วยตนเอง) หาก ฟิลด์ สถานะใน JSON ขาเข้าไม่เท่ากับ: ซูเปอร์ สตาร์ 5) ข้อผิดพลาด KickInTheAssException จะ ต้องได้รับการจัดการโดย ControllerAdviceและเนื้อหาการตอบสนองจะต้องมี ข้อความ: “อย่าให้ฉันเห็นคุณที่นี่อีก! สถานะการตอบสนองควรเป็น 400 6) ข้อผิดพลาดมาตรฐานEntityNotFoundExceptionซึ่งเกิดขึ้น เช่น ถ้ามีเพียง Katy Perry เท่านั้นมาที่คลับและบันทึกลงในฐานข้อมูลด้วยid = 1และคุณเรียกเมธอด"display record by id"และต้องการ เพื่อแสดงบันทึกด้วยid = 2ซึ่งไม่อยู่ในฐานข้อมูล ข้อผิดพลาดนี้ต้องได้รับการจัดการโดยวิธีการแทนที่ของ คลาส ResponseEntityExceptionHandlerซึ่งขึ้นอยู่กับคุณว่าจะคิดออกเอง คำตอบจะต้องมีสถานะที่เหมาะสม 7) ทำการตรวจสอบความถูกต้อง: ตัวเลือกง่ายๆ - ฟิลด์ JSON ต้องไม่เป็นโมฆะ หรือยากกว่านั้น ฟิลด์ "ชื่อ" จะต้องประกอบด้วยคำสองคำของตัวอักษรละติน และทั้งคู่ต้องขึ้นต้นด้วยตัวพิมพ์ใหญ่ ค่าที่ไม่ถูกต้องควรมีข้อยกเว้น จัดการด้วยวิธีใดวิธีหนึ่ง พิมพ์รหัสข้อผิดพลาดที่เหมาะสมและข้อความแสดงข้อผิดพลาด: ไม่มีการตรวจสอบ และนำทั้งหมดนี้ไปใช้โดยไม่ใช้ไลบรารีลอมบอก อย่ารวมไว้เป็นการพึ่งพาโปรเจ็กต์ 😅
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION