JavaRush /Blog Java /Random-VI /Xử lý ngoại lệ trong bộ điều khiển khởi động mùa xuân
Павел
Mức độ

Xử lý ngoại lệ trong bộ điều khiển khởi động mùa xuân

Xuất bản trong nhóm
NỘI DUNG CỦA CHU KỲ BÀI VIẾT Xin chào một lần nữa! Đã đến lúc lau bụi bàn phím của bạn. Tạo một dự án khởi động mùa xuân. Từ các phụ thuộc maven chúng ta cần:
<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>
Trước khi đọc thêm, hãy tạo cấu trúc dự án: Xử lý ngoại lệ trong bộ điều khiển khởi động mùa xuân - 1 BusinessException và CustomException:
public class BusinessException extends Exception{
    public BusinessException(String message) {
        super(message);
    }
}

public class CustomException extends Exception{
    public CustomException(String message) {
        super(message);
    }
}
và lớp Phản hồi
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;
    }
}
Và bây giờ, tôi sẽ thực hiện một thủ thuật bằng đôi tai của mình và nhường chỗ cho Alexey Kutepov, trong bài viết Xử lý ngoại lệ trong Spring Controllers, anh ấy sẽ cho chúng ta biết cách điền nội dung chính xác vào các tệp này. Đọc chậm, sao chép cẩn thận tất cả các ví dụ vào dự án của bạn, chạy và kiểm tra trong Postman. Nếu trong bài viết của Alexey, dòng sau đặt ra câu hỏi cho bạn: production = APPLICATION_JSON_VALUE , thì hãy biết rằng nó không liên quan gì đến việc xử lý ngoại lệ, nó nói rằng theo mặc định, tất cả các phương thức của bộ điều khiển này sẽ trả về JSON. Nếu cần, trong một phương thức cụ thể, giá trị này có thể được ghi đè sang một MediaType khác. Nếu bạn đã đọc nó, hãy tiếp tục. Bài viết trên thảo luận về các tùy chọn khác nhau cho trình xử lý. Linh hoạt nhất trong số đó: @ControllerAdvice - nó cho phép bạn thay đổi cả mã và nội dung của phản hồi tiêu chuẩn trong trường hợp có lỗi. Ngoài ra, nó cho phép bạn xử lý nhiều ngoại lệ cùng một lúc trong một phương thức. Nhưng đó chưa phải là tất cả, nếu bạn đọc thêm, bạn sẽ nhận được @ControllerAdvice cải tiến hoàn toàn miễn phí. Hãy thực hiện một số công việc chuẩn bị: Tôi muốn phản hồi hiển thị cả thông báo lỗi tùy chỉnh và thông báo lỗi tiêu chuẩn. Để làm điều này, hãy thay đổi lớp Phản hồi : thêm một trường nữa
private String debugMessage;
Hãy tạo một hàm tạo bổ sung:
public Response(String message, String debugMessage) {
    this.message = message;
    this.debugMessage = debugMessage;
}
và đừng quên tạo Getter và Setter cho trường mới. Bây giờ đến điểm. Hãy viết một bộ điều khiển khác:
@RestController
public class Example7Controller {
    @GetMapping(value = "/testExtendsControllerAdvice")
    public ResponseEntity<?> testExtendsControllerAdvice(@RequestBody Response response) {
        return  ResponseEntity.ok(response);
    }
}
Hãy kiểm tra người đưa thư: Gửi JSON tới http://localhost:8080/testExtendsControllerAdvice
{
    "message": "message"
}
Để đáp lại, chúng tôi sẽ nhận được trạng thái 200 và nội dung
{
    "message": "message",
    "debugMessage": null
}
Bây giờ chúng tôi sẽ gửi JSON rõ ràng là không chính xác
{
    11"message": "message"
}
Đáp lại, chúng tôi sẽ nhận được trạng thái 400 (nếu bạn quên ý nghĩa của nó, hãy tra cứu trên Internet) và nội dung phản hồi trống. Tất nhiên, không ai hài lòng với điều này, hãy chiến đấu với nó. Trước đây, chúng tôi đã tạo @ControllerAdvice từ đầu, nhưng trong Spring Boot có một mẫu - ResponseEntityExceptionHandler . Nó đã xử lý nhiều trường hợp ngoại lệ, ví dụ: NoHandlerFoundException , HttpMessageNotReadableException , MethodArgumentNotValidException và các ngoại lệ khác. Lớp này xử lý lỗi. Nó có một loạt các phương thức, tên của chúng được đặt theo tên chính + tên ngoại lệ. Nếu chúng ta muốn xử lý một số ngoại lệ cơ bản thì chúng ta kế thừa từ lớp này và ghi đè phương thức mong muốn . Hãy hoàn thiện lớp cố vấn mặc định
@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);
    }
}
Như bạn đã nhận thấy, trình xử lý chịu trách nhiệm về HttpMessageNotReadableException đã bị ghi đè . Ngoại lệ này xảy ra khi không thể đọc được nội dung của yêu cầu đến phương thức bộ điều khiển - ví dụ: JSON không chính xác. Phương thức handHttpMessageNotReadable () chịu trách nhiệm cho ngoại lệ này . Hãy thực hiện lại yêu cầu với JSON không chính xác: tới http://localhost:8080/testExtendsControllerAdvice
{
    11"message": "message"
}
Chúng tôi nhận được phản hồi với mã 400 (Yêu cầu xấu) và nội dung:
{
    "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]"
}
Bây giờ phản hồi không chỉ chứa mã chính xác mà còn chứa nội dung chứa các thông báo chứa nhiều thông tin. Hãy kiểm tra xem nó hoạt động như thế nào với Yêu cầu JSON chính xác:
{
    "message": "message"
}
Chúng tôi đã nhận được câu trả lời:
{
    "message": "message",
    "debugMessage": null
}
Thành thật mà nói, tôi không thích phản hồi chứa trường có giá trị null , chúng tôi sẽ nhanh chóng khắc phục điều đó ngay bây giờ. Chuyển đến lớp Phản hồi và đặt chú thích vào trường bắt buộc
@JsonInclude(JsonInclude.Include.NON_NULL)
private String debugMessage;
Chúng tôi khởi động lại dự án, thực hiện lại yêu cầu trước đó và nhận được phản hồi:
{
    "message": "message"
}
Nhờ chú thích @JsonInclude(JsonInclude.Include.NON_NULL) , trường này sẽ chỉ được đưa vào phản hồi nếu chúng ta chỉ định nó. @JsonInclude được bao gồm trong thư viện chú thích của Jackson , rất hữu ích để biết nó có thể làm gì. Dưới đây là hai bài viết để bạn lựa chọn: Chú thích của Jackson. Tác giả đã dịch nhưng chưa hoàn thành bản dịch ; Google Translit làm rất tốt. Xác nhận Cần phải bổ sung chủ đề này bằng một khái niệm như xác nhận. Nói một cách đơn giản, đây là cách kiểm tra xem đối tượng có phải là đối tượng mà chúng ta mong đợi hay không. Ví dụ: nếu trong ứng dụng “Danh bạ điện thoại”, chúng ta cần kiểm tra sự hiện diện của các số điện thoại trong cơ sở dữ liệu, thì trước khi vào cơ sở dữ liệu, việc kiểm tra xem người dùng đã nhập chữ cái thay vì số hay chưa là điều hợp lý. Ba bài viết về xác thực, với độ phức tạp ngày càng tăng: Xác thực các Bean trong Spring Thiết lập xác thực DTO trong Xác thực dữ liệu Spring Framework trong Spring Boot Chúng ta đã hoàn thành phần lý thuyết cho ngày hôm nay. Để đào tạo, tôi đề xuất nhiệm vụ sau: Bạn cần triển khai ứng dụng NightclubBouncer. Yêu cầu: 1) Ứng dụng phải chấp nhận JSON làm đầu vào và ghi vào cơ sở dữ liệu. Ví dụ về JSON:
{
    "name": "Katy Perry"
    “status”:super star”
}
Và phần nội dung phản hồi phải có dòng chữ sau: Chào mừng + tên ! 2) Ứng dụng phải triển khai các phương thức sau: - xuất bản ghi theo id từ cơ sở dữ liệu đến máy khách (Người đưa thư). - xóa bản ghi theo trường: tên . 3) Phải triển khai ánh xạ từ lớp dto tới thực thể và ngược lại . 4) Ứng dụng phải đưa ra lỗi KickInTheAssException (bạn cần tự phát triển) nếu trường trạng thái trong JSON đến không bằng: super star 5) Lỗi KickInTheAssException phải được xử lý bởi ControllerAdvice và nội dung phản hồi phải chứa nội dung tin nhắn: “Đừng để tôi gặp lại bạn ở đây! Trạng thái phản hồi phải là 400. 6) Lỗi tiêu chuẩn EntityNotFoundException , xảy ra, ví dụ: nếu chỉ Katy Perry đến câu lạc bộ và lưu vào cơ sở dữ liệu với id = 1 , và bạn đã gọi phương thức "hiển thị bản ghi theo id" và muốn để hiển thị bản ghi có id = 2 , không có trong cơ sở dữ liệu. Lỗi này phải được xử lý bằng một phương thức được ghi đè của lớp ResponseEntityExceptionHandler , phương thức nào tùy thuộc vào bạn để tự tìm ra. Phản hồi phải có trạng thái thích hợp. 7) Thực hiện xác thực: một tùy chọn đơn giản - các trường JSON không được rỗng hoặc khó hơn, trường "tên" phải bao gồm hai từ trong bảng chữ cái Latinh và cả hai đều phải bắt đầu bằng chữ in hoa. Các giá trị không hợp lệ sẽ đưa ra một ngoại lệ, xử lý nó theo bất kỳ cách nào, in mã lỗi thích hợp và thông báo lỗi: Không xác thực. Và triển khai tất cả những điều này mà không cần sử dụng thư viện Lombok, đừng đưa nó vào làm phần phụ thuộc của dự án 😅
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION