JavaRush /Blog Java /Random-MS /Pengendalian Pengecualian dalam Pengawal But Spring

Pengendalian Pengecualian dalam Pengawal But Spring

Diterbitkan dalam kumpulan
KANDUNGAN KITARAN ARTIKEL Hello sekali lagi! Sudah tiba masanya untuk membersihkan papan kekunci anda. Buat projek spring-boot. Dari kebergantungan maven yang kita perlukan:
<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>
Sebelum membaca lebih lanjut, buat struktur projek: Pengendalian Pengecualian dalam Pengawal But Spring - 1 BusinessException dan CustomException:
public class BusinessException extends Exception{
    public BusinessException(String message) {
        super(message);
    }
}

public class CustomException extends Exception{
    public CustomException(String message) {
        super(message);
    }
}
dan kelas Respons
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;
    }
}
Dan sekarang, saya akan melakukan helah dengan telinga saya dan memberikan lantai kepada Alexey Kutepov, dalam artikelnya Pengendalian Pengecualian dalam Pengawal Musim Bunga, dia akan memberitahu kami cara mengisi fail ini dengan kandungan yang betul. Baca perlahan-lahan, salin semua contoh dengan teliti ke dalam projek anda, jalankan dan uji dalam Posman. Jika dalam artikel Alexey baris berikut menimbulkan soalan untuk anda: menghasilkan = APPLICATION_JSON_VALUE , maka ketahui bahawa ia tiada kaitan dengan pengendalian pengecualian, ia mengatakan bahawa secara lalai semua kaedah pengawal ini akan mengembalikan JSON. Jika perlu, dalam kaedah tertentu, nilai ini boleh ditindih kepada MediaType lain. Jika anda telah membacanya, teruskan. Artikel di atas membincangkan pilihan yang berbeza untuk pengendali. Yang paling fleksibel antaranya: @ControllerAdvice - ia membolehkan anda menukar kedua-dua kod dan badan respons standard sekiranya berlaku ralat. Selain itu, ia membolehkan anda mengendalikan berbilang pengecualian sekaligus dalam satu kaedah. Tetapi bukan itu sahaja, jika anda membaca lebih lanjut, anda akan mendapat @ControllerAdvice yang dipertingkatkan sepenuhnya secara percuma. Mari lakukan beberapa kerja persediaan: Saya mahu respons memaparkan kedua-dua mesej ralat tersuai dan standard. Untuk melakukan ini, mari buat perubahan pada kelas Respons : tambah satu lagi medan
private String debugMessage;
Mari buat pembina tambahan:
public Response(String message, String debugMessage) {
    this.message = message;
    this.debugMessage = debugMessage;
}
dan jangan lupa buat Getter dan Setter untuk medan baharu. Sekarang ke titik. Mari tulis pengawal lain:
@RestController
public class Example7Controller {
    @GetMapping(value = "/testExtendsControllerAdvice")
    public ResponseEntity<?> testExtendsControllerAdvice(@RequestBody Response response) {
        return  ResponseEntity.ok(response);
    }
}
Mari uji dalam posmen: Hantar JSON ke http://localhost:8080/testExtendsControllerAdvice
{
    "message": "message"
}
Sebagai tindak balas kami akan menerima status 200 dan badan
{
    "message": "message",
    "debugMessage": null
}
Sekarang kami akan menghantar JSON yang jelas salah
{
    11"message": "message"
}
Sebagai balasan, kami akan menerima status 400 (jika anda terlupa maksudnya, cari di Internet) dan badan respons kosong. Sudah tentu, tiada siapa yang gembira dengan ini, mari kita lawannya. Sebelum ini, kami mencipta @ControllerAdvice dari awal, tetapi dalam Spring Boot terdapat templat - ResponseEntityExceptionHandler . Ia sudah mengendalikan banyak pengecualian, contohnya: NoHandlerFoundException , HttpMessageNotReadableException , MethodArgumentNotValidException dan lain-lain. Kelas ini mengendalikan ralat. Ia mempunyai banyak kaedah, yang namanya berdasarkan pemegang prinsip + nama pengecualian. Jika kita ingin mengendalikan beberapa pengecualian asas, maka kita mewarisi daripada kelas ini dan mengatasi kaedah yang diingini . Mari kita akhiri kelas nasihat lalai
@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);
    }
}
Seperti yang anda perhatikan, pengendali yang bertanggungjawab untuk HttpMessageNotReadableException telah ditindih . Pengecualian ini berlaku apabila badan permintaan yang datang ke kaedah pengawal tidak boleh dibaca - contohnya, JSON yang salah. Kaedah handleHttpMessageNotReadable () bertanggungjawab untuk pengecualian ini . Mari buat permintaan sekali lagi dengan JSON yang salah: ke http://localhost:8080/testExtendsControllerAdvice
{
    11"message": "message"
}
Kami menerima respons dengan kod 400 (Permintaan Buruk) dan isinya:
{
    "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]"
}
Kini respons mengandungi bukan sahaja kod yang betul, tetapi juga badan dengan mesej bermaklumat. Mari semak cara ia berfungsi dengan Permintaan JSON yang betul:
{
    "message": "message"
}
Kami menerima jawapannya:
{
    "message": "message",
    "debugMessage": null
}
Sejujurnya, saya tidak suka bahawa respons mengandungi medan dengan nilai null , kami akan segera membetulkannya sekarang. Pergi ke kelas Respons dan letakkan anotasi pada medan yang diperlukan
@JsonInclude(JsonInclude.Include.NON_NULL)
private String debugMessage;
Kami memulakan semula projek, membuat permintaan sebelumnya sekali lagi, dan dalam respons kami mendapat:
{
    "message": "message"
}
Terima kasih kepada anotasi @JsonInclude(JsonInclude.Include.NON_NULL) , medan ini hanya akan disertakan dalam respons jika kami menyatakannya. @JsonInclude disertakan dalam perpustakaan anotasi Jackson , sangat berguna untuk mengetahui perkara yang boleh dilakukannya. Berikut ialah dua artikel untuk dipilih: Anotasi Jackson. Pengarang menterjemah, tetapi tidak menyelesaikan terjemahan ; Google Translit melakukan kerja yang hebat. Pengesahan Adalah perlu untuk menambah topik ini dengan konsep seperti pengesahan. Ringkasnya, ini adalah semakan bahawa objek itu adalah objek yang kita harapkan. Sebagai contoh: jika dalam aplikasi "Direktori Telefon" kita perlu menyemak kehadiran nombor telefon dalam pangkalan data, maka sebelum masuk ke pangkalan data, adalah logik untuk menyemak sama ada pengguna telah memasukkan huruf dan bukannya nombor. Tiga artikel mengenai pengesahan, dalam meningkatkan kerumitan: Pengesahan kacang dalam Spring Menyediakan pengesahan DTO dalam Rangka Kerja Spring Pengesahan data dalam Spring Boot Kami telah selesai dengan teori untuk hari ini. Untuk latihan, saya mencadangkan tugasan berikut: Anda perlu melaksanakan aplikasi NightclubBouncer. Keperluan: 1) Aplikasi mesti menerima JSON sebagai input dan menulis ke pangkalan data. Contoh JSON:
{
    "name": "Katy Perry"
    “status”:super star”
}
Dan badan respons harus mengandungi inskripsi berikut: Selamat Datang + nama ! 2) Aplikasi mesti melaksanakan kaedah berikut: - mengeluarkan rekod dengan id dari pangkalan data kepada pelanggan (Postmen). - memadam rekod mengikut medan: nama . 3) Pemetaan dari lapisan dto ke entiti dan belakang mesti dilaksanakan . 4) Aplikasi mesti membuang ralat KickInTheAssException (anda perlu membangunkannya sendiri) jika medan status dalam JSON masuk tidak sama dengan: bintang super 5) Ralat KickInTheAssException mesti dikendalikan oleh ControllerAdvice , dan badan tindak balas mesti mengandungi mesej: “Jangan benarkan saya jumpa awak di sini lagi! Status respons hendaklah 400. 6) Ralat standard EntityNotFoundException , yang berlaku, sebagai contoh, jika Katy Perry datang ke kelab dan disimpan ke pangkalan data dengan id = 1 , dan anda memanggil kaedah "rekod paparan mengikut id" dan mahu untuk memaparkan rekod dengan id = 2 , yang tiada dalam pangkalan data. Ralat ini mesti dikendalikan oleh kaedah ganti kelas ResponseEntityExceptionHandler , yang mana satu terpulang kepada anda untuk memikirkan sendiri. Jawapan mesti mempunyai status yang sesuai. 7) Lakukan pengesahan: pilihan mudah - medan JSON mestilah tidak batal, atau lebih sukar, medan "nama" mesti terdiri daripada dua perkataan abjad Latin dan kedua-duanya mesti bermula dengan huruf besar. Nilai tidak sah harus membuang pengecualian, mengendalikannya dalam apa cara sekalipun, mencetak kod ralat yang sesuai dan mesej ralat: Tiada pengesahan. Dan laksanakan semua ini tanpa menggunakan perpustakaan Lombok, jangan masukkan sebagai tanggungan projek 😅
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION