JavaRush /Java Blog /Random-ID /Penanganan Pengecualian di Pengontrol Boot Musim Semi
Павел
Level 11

Penanganan Pengecualian di Pengontrol Boot Musim Semi

Dipublikasikan di grup Random-ID
ISI SIKLUS PASAL Halo lagi! Saatnya membersihkan keyboard Anda. Buat proyek booting pegas. Dari dependensi pakar 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 proyek: Penanganan Pengecualian di Pengontrol Boot Musim Semi - 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 Respon
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 trik dengan telinga saya dan memberikan penjelasan kepada Alexei Kutepov, dalam artikelnya Penanganan Pengecualian di Pengendali Musim Semi, dia akan memberi tahu kami cara mengisi file-file ini dengan konten yang benar. Baca perlahan, salin semua contoh dengan hati-hati ke dalam proyek Anda, jalankan dan uji di Tukang Pos. Jika dalam artikel Alexei baris berikut menimbulkan pertanyaan untuk Anda: menghasilkan = APPLICATION_JSON_VALUE , maka ketahuilah bahwa ini tidak ada hubungannya dengan penanganan pengecualian, dikatakan bahwa secara default semua metode pengontrol ini akan mengembalikan JSON. Jika perlu, dalam metode tertentu, nilai ini dapat diganti ke MediaType lain. Jika Anda sudah membacanya, lanjutkan. Artikel di atas membahas berbagai opsi untuk penangan. Yang paling fleksibel di antaranya: @ControllerAdvice - memungkinkan Anda mengubah kode dan isi respons standar jika terjadi kesalahan. Selain itu, ini memungkinkan Anda menangani banyak pengecualian sekaligus dalam satu metode. Namun bukan itu saja, jika Anda membaca lebih lanjut, Anda akan mendapatkan @ControllerAdvice yang ditingkatkan sepenuhnya gratis. Mari kita lakukan beberapa pekerjaan persiapan: Saya ingin respons menampilkan pesan kesalahan khusus dan standar. Untuk melakukan hal ini, mari kita buat perubahan pada kelas Response : tambahkan satu field lagi
private String debugMessage;
Mari buat konstruktor tambahan:
public Response(String message, String debugMessage) {
    this.message = message;
    this.debugMessage = debugMessage;
}
dan jangan lupa membuat Getter dan Setter untuk field baru. Sekarang langsung ke intinya. Mari kita tulis pengontrol lain:
@RestController
public class Example7Controller {
    @GetMapping(value = "/testExtendsControllerAdvice")
    public ResponseEntity<?> testExtendsControllerAdvice(@RequestBody Response response) {
        return  ResponseEntity.ok(response);
    }
}
Mari kita uji di tukang pos: Kirim JSON ke http://localhost:8080/testExtendsControllerAdvice
{
    "message": "message"
}
Sebagai tanggapan, kami akan menerima status 200 dan satu badan
{
    "message": "message",
    "debugMessage": null
}
Sekarang kami akan mengirimkan JSON yang jelas-jelas salah
{
    11"message": "message"
}
Sebagai tanggapan, kami akan menerima status 400 (jika Anda lupa artinya, cari di Internet) dan isi tanggapan kosong. Tentu saja tidak ada yang senang dengan hal ini, mari kita lawan. Sebelumnya, kami membuat @ControllerAdvice dari awal, tetapi di Spring Boot ada template - ResponseEntityExceptionHandler . Ini sudah menangani banyak pengecualian, misalnya: NoHandlerFoundException , HttpMessageNotReadableException , MethodArgumentNotValidException dan lain-lain. Kelas ini menangani kesalahan. Ia memiliki banyak metode, yang namanya didasarkan pada prinsip pegangan + nama pengecualian. Jika kita ingin menangani beberapa pengecualian dasar, maka kita mewarisi dari kelas ini dan mengganti metode yang diinginkan . Mari selesaikan kelas penasehat default
@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 bertanggung jawab atas HttpMessageNotReadableException telah diganti . Pengecualian ini terjadi ketika isi permintaan yang masuk ke metode pengontrol tidak dapat dibaca - misalnya, JSON salah. Metode handleHttpMessageNotReadable () bertanggung jawab atas pengecualian ini . Mari kita buat permintaan lagi dengan JSON yang salah: ke http://localhost:8080/testExtendsControllerAdvice
{
    11"message": "message"
}
Kami menerima respons dengan kode 400 (Permintaan Buruk) dan isi:
{
    "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]"
}
Sekarang responsnya tidak hanya berisi kode yang benar, tetapi juga isi pesan informatif. Mari kita periksa cara kerjanya dengan Permintaan JSON yang benar:
{
    "message": "message"
}
Kami menerima jawabannya:
{
    "message": "message",
    "debugMessage": null
}
Sejujurnya, saya tidak suka responsnya berisi bidang dengan nilai null , kami akan segera memperbaikinya sekarang. Buka kelas Respons dan beri anotasi pada bidang yang wajib diisi
@JsonInclude(JsonInclude.Include.NON_NULL)
private String debugMessage;
Kami memulai ulang proyek, membuat permintaan sebelumnya lagi, dan sebagai tanggapan kami mendapatkan:
{
    "message": "message"
}
Berkat anotasi @JsonInclude(JsonInclude.Include.NON_NULL) , bidang ini hanya akan disertakan dalam respons jika kita menentukannya. @JsonInclude disertakan dalam perpustakaan anotasi Jackson , sangat berguna untuk mengetahui apa yang dapat dilakukannya. Berikut dua artikel yang dapat dipilih: Anotasi Jackson. Penulis menerjemahkan, namun tidak menyelesaikan terjemahannya ; Google Translit berfungsi dengan baik. Validasi Topik ini perlu dilengkapi dengan konsep seperti validasi. Sederhananya, ini adalah pengecekan bahwa objek tersebut adalah objek yang kita harapkan. Misal: jika pada aplikasi “Direktori Telepon” kita perlu memeriksa keberadaan nomor telepon di database, maka sebelum masuk ke database, logis untuk memeriksa apakah pengguna telah memasukkan huruf, bukan angka. Tiga artikel tentang validasi, dengan kompleksitas yang semakin meningkat: Validasi kacang di Spring Menyiapkan validasi DTO di Spring Framework Validasi data di Spring Boot Kita sudah selesai dengan teori hari ini. Untuk pelatihan, saya menyarankan tugas berikut: Anda perlu mengimplementasikan aplikasi NightclubBouncer. Persyaratan: 1) Aplikasi harus menerima JSON sebagai input dan menulis ke database. Contoh JSON:
{
    "name": "Katy Perry"
    “status”:super star”
}
Dan isi tanggapan harus berisi tulisan berikut: Selamat datang + nama ! 2) Aplikasi harus menerapkan metode berikut: - mengeluarkan catatan berdasarkan id dari database ke klien (Tukang Pos). - menghapus catatan berdasarkan bidang: nama . 3) Pemetaan dari lapisan dto ke entitas dan sebaliknya harus diimplementasikan . 4) Aplikasi harus memunculkan kesalahan KickInTheAssException (Anda perlu mengembangkannya sendiri) jika bidang status di JSON yang masuk tidak sama dengan: super star 5) Kesalahan KickInTheAssException harus ditangani oleh ControllerAdvice , dan badan respons harus berisi pesan: “Jangan biarkan aku melihatmu di sini lagi! Status responsnya harus 400. 6) Kesalahan standar EntityNotFoundException , yang terjadi, misalnya, jika hanya Katy Perry yang datang ke klub dan menyimpan ke database dengan id = 1 , dan Anda memanggil metode "tampilkan catatan berdasarkan id" dan ingin untuk menampilkan catatan dengan id = 2 , yang tidak ada dalam database. Kesalahan ini harus ditangani dengan metode kelas ResponseEntityExceptionHandler yang diganti , yang mana terserah Anda untuk mencari tahu sendiri. Responsnya harus memiliki status yang sesuai. 7) Lakukan validasi: opsi sederhana - bidang JSON tidak boleh nol, atau lebih sulit, bidang "nama" harus terdiri dari dua kata alfabet Latin dan keduanya harus dimulai dengan huruf kapital. Nilai yang tidak valid harus memunculkan pengecualian, menanganinya dengan cara apa pun, mencetak kode kesalahan yang sesuai dan pesan kesalahan: Tidak ada validasi. Dan implementasikan semua ini tanpa menggunakan perpustakaan Lombok, jangan sertakan sebagai ketergantungan proyek 😅
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION