JavaRush /Java-Blog /Random-DE /Ausnahmebehandlung in Spring Boot Controllern
Павел
Level 11

Ausnahmebehandlung in Spring Boot Controllern

Veröffentlicht in der Gruppe Random-DE
INHALT DES ARTIKELZYKLUS Hallo nochmal! Es ist Zeit, Ihre Tastatur abzustauben. Erstellen Sie ein Spring-Boot-Projekt. Von den Maven-Abhängigkeiten benötigen wir:
<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>
Bevor Sie weiterlesen, erstellen Sie eine Projektstruktur: Ausnahmebehandlung in Spring Boot Controllern – 1 BusinessException und CustomException:
public class BusinessException extends Exception{
    public BusinessException(String message) {
        super(message);
    }
}

public class CustomException extends Exception{
    public CustomException(String message) {
        super(message);
    }
}
und die Response- Klasse
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;
    }
}
Und jetzt mache ich einen Trick mit meinen Ohren und erteile Alexey Kutepov das Wort. In seinem Artikel „ Exception Handling in Spring Controllers“ wird er uns erklären, wie wir diese Dateien mit dem richtigen Inhalt füllen. Lesen Sie langsam, kopieren Sie alle Beispiele sorgfältig in Ihr Projekt, führen Sie sie aus und testen Sie sie in Postman. Wenn in Alexeys Artikel die folgende Zeile Fragen für Sie aufgeworfen hat: „ produziert = APPLICATION_JSON_VALUE“ , dann wissen Sie, dass dies nichts mit der Ausnahmebehandlung zu tun hat. Sie besagt, dass standardmäßig alle Methoden dieses Controllers JSON zurückgeben. Bei Bedarf kann dieser Wert in einer bestimmten Methode durch einen anderen MediaType überschrieben werden. Wenn Sie ihn gelesen haben, fahren Sie fort. Im obigen Artikel werden verschiedene Optionen für Handler erläutert. Das flexibelste davon: @ControllerAdvice – es ermöglicht Ihnen, im Fehlerfall sowohl den Code als auch den Text der Standardantwort zu ändern. Darüber hinaus können Sie mehrere Ausnahmen gleichzeitig in einer Methode behandeln. Aber das ist noch nicht alles, wenn Sie weiterlesen, erhalten Sie das verbesserte @ControllerAdvice völlig kostenlos. Machen wir einige vorbereitende Arbeiten: Ich möchte, dass die Antwort sowohl benutzerdefinierte als auch Standardfehlermeldungen anzeigt. Nehmen wir dazu eine Änderung an der Response- Klasse vor : Fügen Sie ein weiteres Feld hinzu
private String debugMessage;
Erstellen wir einen zusätzlichen Konstruktor:
public Response(String message, String debugMessage) {
    this.message = message;
    this.debugMessage = debugMessage;
}
und vergessen Sie nicht, einen Getter und einen Setter für das neue Feld zu erstellen. Nun zur Sache. Schreiben wir einen weiteren Controller:
@RestController
public class Example7Controller {
    @GetMapping(value = "/testExtendsControllerAdvice")
    public ResponseEntity<?> testExtendsControllerAdvice(@RequestBody Response response) {
        return  ResponseEntity.ok(response);
    }
}
Testen wir im Postman: Senden Sie JSON an http://localhost:8080/testExtendsControllerAdvice
{
    "message": "message"
}
Als Antwort erhalten wir einen Status von 200 und einen Körper
{
    "message": "message",
    "debugMessage": null
}
Jetzt senden wir offensichtlich falsches JSON
{
    11"message": "message"
}
Als Antwort erhalten wir den Status 400 (falls Sie vergessen haben, was das bedeutet, schauen Sie im Internet nach) und einen leeren Antworttext. Natürlich ist niemand damit zufrieden, lasst uns dagegen ankämpfen. Zuvor haben wir @ControllerAdvice von Grund auf erstellt, aber in Spring Boot gibt es eine Vorlage – ResponseEntityExceptionHandler . Es behandelt bereits viele Ausnahmen, zum Beispiel: NoHandlerFoundException , HttpMessageNotReadableException , MethodArgumentNotValidException und andere. Diese Klasse behandelt Fehler. Es verfügt über eine Reihe von Methoden, deren Namen auf dem Prinzip Handle + Ausnahmename basieren . Wenn wir eine grundlegende Ausnahme behandeln möchten, erben wir von dieser Klasse und überschreiben die gewünschte Methode . Lassen Sie uns die Standard-Beratungsklasse fertigstellen
@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 oder другим, тут ограничений нет,
//попробуйте поменять статусы и потестить этот обработчик


    @Override//переопределoder метод родительского класса
    protected ResponseEntity<Object> handleHttpMessageNotReadable
            (HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        Response response = new Response("Не правильный JSON",ex.getMessage());
        return new ResponseEntity<>(response, status);
    }
}
Wie Sie bemerkt haben, wurde der für HttpMessageNotReadableException verantwortliche Handler überschrieben . Diese Ausnahme tritt auf, wenn der Hauptteil der an die Controller-Methode eingehenden Anforderung nicht lesbar ist – beispielsweise falsches JSON. Für diese Ausnahme ist die Methode handleHttpMessageNotReadable () verantwortlich . Stellen wir erneut eine Anfrage mit falschem JSON: an http://localhost:8080/testExtendsControllerAdvice
{
    11"message": "message"
}
Wir erhalten eine Antwort mit dem Code 400 (Bad Request) und dem Text:
{
    "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]"
}
Jetzt enthält die Antwort nicht nur den richtigen Code, sondern auch einen Text mit informativen Nachrichten. Schauen wir uns an, wie es mit der richtigen JSON-Anfrage funktioniert:
{
    "message": "message"
}
Wir haben die Antwort erhalten:
{
    "message": "message",
    "debugMessage": null
}
Ehrlich gesagt gefällt mir nicht, dass die Antwort ein Feld mit dem Wert null enthält , das werden wir jetzt schnell beheben. Gehen Sie zur Response -Klasse und fügen Sie eine Anmerkung über das erforderliche Feld ein
@JsonInclude(JsonInclude.Include.NON_NULL)
private String debugMessage;
Wir starten das Projekt neu, stellen die vorherige Anfrage erneut und erhalten als Antwort Folgendes:
{
    "message": "message"
}
Dank der Annotation @JsonInclude(JsonInclude.Include.NON_NULL) wird dieses Feld nur dann in die Antwort aufgenommen, wenn wir es angeben. @JsonInclude ist in der Jackson- Annotationsbibliothek enthalten . Es ist sehr nützlich zu wissen, was es kann. Hier stehen zwei Artikel zur Auswahl: Jackson-Anmerkungen. Der Autor hat übersetzt, die Übersetzung jedoch nicht abgeschlossen ; Google Translit leistet hervorragende Arbeit. Validierung Es ist notwendig, dieses Thema durch ein Konzept wie die Validierung zu ergänzen. Einfach ausgedrückt ist dies eine Überprüfung, ob das Objekt das Objekt ist, das wir erwarten. Beispiel: Wenn wir in der Anwendung „Telefonbuch“ das Vorhandensein von Telefonnummern in der Datenbank überprüfen müssen, ist es logisch, vor dem Aufrufen der Datenbank zu prüfen, ob der Benutzer Buchstaben anstelle von Zahlen eingegeben hat. Drei Artikel zur Validierung, in zunehmender Komplexität: Validierung von Beans in Spring Einrichten der DTO-Validierung im Spring Framework Datenvalidierung in Spring Boot Für heute sind wir mit der Theorie fertig. Für das Training schlage ich folgende Aufgabe vor: Sie müssen die NightclubBouncer-Anwendung implementieren. Anforderungen: 1) Die Anwendung muss JSON als Eingabe akzeptieren und in die Datenbank schreiben. JSON-Beispiel:
{
    "name": "Katy Perry"
    “status”:super star”
}
Und der Text der Antwort sollte die folgende Aufschrift enthalten: Willkommen + Name ! 2) Die Anwendung muss die folgenden Methoden implementieren: - Ausgabe eines Datensatzes nach ID aus der Datenbank an den Client (Postman). - Löschen eines Datensatzes nach Feld: Name . 3) Die Zuordnung von der DTO- Ebene zur Entität und zurück muss implementiert werden . 4) Die Anwendung muss einen KickInTheAssException- Fehler auslösen (Sie müssen ihn selbst entwickeln), wenn das Statusfeld im eingehenden JSON nicht gleich ist: super star 5) Der KickInTheAssException -Fehler muss von ControllerAdvice behandelt werden und der Antworttext muss Folgendes enthalten Nachricht: „Lass mich dich hier nicht noch einmal sehen!“ Der Antwortstatus sollte 400 sein. 6) Standardfehler EntityNotFoundException , der beispielsweise auftritt, wenn nur Katy Perry zum Club kam und mit id = 1 in der Datenbank gespeichert wurde und Sie die Methode „Datensatz nach ID anzeigen“ aufgerufen und gewünscht haben um den Datensatz mit der ID = 2 anzuzeigen , der nicht in der Datenbank vorhanden ist. Dieser Fehler muss von einer überschriebenen Methode der ResponseEntityExceptionHandler- Klasse behandelt werden . Welche Methode Sie selbst herausfinden müssen, liegt bei Ihnen. Die Antwort muss den entsprechenden Status haben. 7) Führen Sie die Validierung durch: eine einfache Option – die JSON-Felder dürfen nicht null sein, oder schwieriger, das Feld „Name“ muss aus zwei Wörtern des lateinischen Alphabets bestehen und beide müssen mit einem Großbuchstaben beginnen. Ungültige Werte sollten eine Ausnahme auslösen, auf irgendeine Weise damit umgehen und den entsprechenden Fehlercode und die Fehlermeldung ausgeben: Keine Validierung. Und implementieren Sie das alles, ohne die Lombok-Bibliothek zu verwenden, und fügen Sie sie nicht als Projektabhängigkeit ein 😅
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION