[JAVA] Passen Sie die Antwort auf REST-API-Fehler mit Spring Boot an (Teil 1).

Überblick

Ich habe versucht, die Antwort zum Zeitpunkt des Fehlers mit Spring Boot anzupassen, daher werde ich sie hier als Memorandum beschreiben. Dieses Mal möchte ich den Körperteil der Antwort wie folgt anpassen.

Vorher ändern

{
  "timestamp": "2019-03-14T15:07:50.631+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "MyException ist aufgetreten",
  "path": "/××××/××××"
}

Nach der veränderung

{
  "timestamp": "2019-03-14T15:07:50.631+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "MyException ist aufgetreten",
  "path": "/××××/××××",
  "errorDetail": {
    "detailMessage": "××××××××××××"
  }
}

Voraussetzungen

Umgebung

Prozessablauf

Die folgenden vier Zeichen sind diesmal ungefähr die Zeichen.

Darüber hinaus ist der allgemeine Ablauf des von nun an zu implementierenden Prozesses wie folgt.

  1. Explizites "Werfen" vom Controller mit Ihrer eigenen definierten Ausnahme zur gleichen Zeit wie die Anforderung
  2. (Erstellen Sie eine Klasse, die die Ausnahme behandelt.) Fangen Sie die ausgelöste Ausnahme mit der Handle-Klasse ab
  3. Gibt einen benutzerdefinierten Antworttext zurück

Danach werden wir die obige Verarbeitung implementieren. (Obwohl die Bestellung nicht in Ordnung ist ...)

Implementierung

Zuordnung der Klassendefinition

Hier definieren wir die Mapping-Klasse für den Antworttext.

ErrorResponseBody.java


package com.example.demo.errorResponse;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Setter;

import java.time.ZonedDateTime;

@Setter
public class ErrorResponseBody {

        @JsonProperty("timestamp")
        private ZonedDateTime exceptionOccurrenceTime;
        @JsonProperty("status")
        private int status;
        @JsonProperty("error")
        private String error;
        @JsonProperty("message")
        private String message;
        @JsonProperty("path")
        private String path;
        @JsonProperty("errorDetail")
        private ErrorDetail errorDetail;
}

ErrorDetail.java


package com.example.demo.errorResponse;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Setter;

@Setter
public class ErrorDetail {
    @JsonProperty("detailMessage")
    String detailMessage;
}

Definition der eindeutigen Ausnahmeklasse

MyException.java


package com.example.demo.errorResponse;

import lombok.Getter;

@Getter
public class MyException extends RuntimeException {

    private ErrorDetail errorDetails;

    public MyException(String message, ErrorDetail errorDetails) {
        super(message);
        this.errorDetails = errorDetails;
    }
}

Controller-Definition

HelloController.java


package com.example.demo.errorResponse;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/exceptionhandle")
public class HelloController {

    @RequestMapping("/test")
    public String get() {
        ErrorDetail errorDetail = new ErrorDetail();
        errorDetail.setDetailMessage("Detaillierte Nachricht");
        throw new MyException("MyException ist aufgetreten", errorDetail);
    }
}

Ausnahmehandler-Klassendefinition

Dies ist der wichtigste Teil. Es gibt vier Punkte.

  1. Fügen Sie der Handle-Klasse die Annotation @ RestControllerAdvice hinzu
  2. Erben Sie die Klasse ResponseEntityExceptionHandler
  3. Fügen Sie die Annotation @ ExceptionHandler hinzu und geben Sie die eindeutig definierte Ausnahmeklasse an, die ergänzt werden soll.
  4. Übergeben Sie die Instanz der für den Antworttext definierten Klasse an den zweiten Parameter der Methode "super.handleExceptionInternal" (abgesehen davon sind die Argumente dieser Methode in der folgenden Reihenfolge).

Und schließlich wird "ResponseEntity" zurückgegeben.

HelloExceptionHandler.java


package com.example.demo.errorResponse;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.time.ZonedDateTime;

@RestControllerAdvice
public class HelloExceptionHandler extends ResponseEntityExceptionHandler {
    //Catch MyException vom Controller ausgelöst
    @ExceptionHandler(MyException.class)
    public ResponseEntity<Object> handleMyException(MyException exception, WebRequest request) {
        HttpHeaders headers = new HttpHeaders();

        return super.handleExceptionInternal(exception,
                createErrorResponseBody(exception, request),
                headers,
                HttpStatus.BAD_REQUEST,
                request);
    }

    //Erstellen Sie den Hauptteil der Antwort
    private ErrorResponseBody createErrorResponseBody(MyException exception, WebRequest request) {

        ErrorResponseBody errorResponseBody = new ErrorResponseBody();
        int responseCode = HttpStatus.BAD_REQUEST.value();
        String responseErrorMessage = HttpStatus.BAD_REQUEST.getReasonPhrase();
        String uri = ((ServletWebRequest) request).getRequest().getRequestURI();

        errorResponseBody.setExceptionOccurrenceTime(ZonedDateTime.now());
        errorResponseBody.setStatus(responseCode);
        errorResponseBody.setError(responseErrorMessage);
        errorResponseBody.setMessage(exception.getMessage());
        errorResponseBody.setPath(uri);
        errorResponseBody.setErrorDetail(exception.getErrorDetails());

        return errorResponseBody;
    }
}

Abgesehen davon sieht die handleExceptionInternal -Methode der übergeordneten Klasse ResponseEntityExceptionHandler wie folgt aus: Der Teil, der die Instanz für die Fehlerantwort übergibt, ist "@Nullable Object body". Wenn Sie ihn also nicht ordnungsgemäß übergeben, wird der Körperteil nicht angezeigt.

ResponseEntityExceptionHandler.java


	/**
	 * A single place to customize the response body of all Exception types.
	 * <p>The default implementation sets the {@link WebUtils#ERROR_EXCEPTION_ATTRIBUTE}
	 * request attribute and creates a {@link ResponseEntity} from the given
	 * body, headers, and status.
	 * @param ex the exception
	 * @param body the body for the response
	 * @param headers the headers for the response
	 * @param status the response status
	 * @param request the current request
	 */
	protected ResponseEntity<Object> handleExceptionInternal(
			Exception ex, @Nullable Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {

		if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
			request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
		}
		return new ResponseEntity<>(body, headers, status);
	}

Ergebnis

{
  "timestamp": "2019-03-18T10:11:13.795+09:00",
  "status": 400,
  "error": "Bad Request",
  "message": "MyException ist aufgetreten",
  "path": "/exceptionhandle/test",
  "errorDetail": {
    "detailMessage": "Detaillierte Nachricht"
  }
}

In Verbindung stehender Artikel

Anpassen der REST-API-Fehlerantwort mit Spring Boot (Teil 2)

Referenzartikel

Dieses Mal habe ich beim Schreiben des Artikels auf den folgenden Artikel verwiesen.

Passen Sie die Fehlerantwort der von Spring Boot erstellten REST-API an Fehlerbehandlung mit Spring Boot Ausnahmen mit @ RestController von Spring Boot behandeln

Recommended Posts

Passen Sie die Antwort auf REST-API-Fehler mit Spring Boot an (Teil 1).
Hallo Welt (REST API) mit Apache Camel + Spring Boot 2
[Spring Boot] Benutzerinformationen mit Rest API abrufen (Anfänger)
Implementieren Sie eine einfache Rest-API mit Spring Security mit Spring Boot 2.0
Feder mit Kotorin --4 REST API Design
REST-API-Test mit REST Assured Part 2
Implementieren Sie die REST-API mit Spring Boot
Implementieren Sie die REST-API mit Spring Boot und JPA (Application Layer).
Implementieren Sie die REST-API mit Spring Boot und JPA (Infrastructure Layer).
Implementieren Sie die REST-API mit Spring Boot und JPA (Domain Layer Edition).
Implementieren Sie eine einfache Rest-API mit Spring Security & JWT mit Spring Boot 2.0
Implementieren Sie einen einfachen Web-REST-API-Server mit Spring Boot + MySQL
Ändern Sie die Spring Boot REST API-Anforderung / Antwort von CamelCase in SankeCase
[Anfänger] Versuchen Sie, die REST-API für die Todo-App mit Spring Boot zu schreiben
Erstellen Sie einen Web-API-Server mit Spring Boot
Mit Spring Boot herunterladen
Ich habe mit Spring Framework eine API-Domain erstellt. Teil 2
Ordnen Sie DTO automatisch Entitäten mit der Spring Boot-API zu
Erweitern Sie Spring Boot DefaultErrorViewResolver, um Fehlerbildschirme dynamisch anzupassen
Ein Memorandum beim Erstellen eines REST-Service mit Spring Boot
Ich habe mit Spring Framework eine API-Domain erstellt. Teil 1
Führen Sie swagger-ui in die in Spring Boot implementierte REST-API ein
Generieren Sie mit Spring Boot einen Barcode
Hallo Welt mit Spring Boot
Implementieren Sie GraphQL mit Spring Boot
Hallo Welt mit Spring Boot!
Führen Sie LIFF mit Spring Boot aus
SNS-Login mit Spring Boot
Datei-Upload mit Spring Boot
Spring Boot beginnt mit dem Kopieren
Spring Boot beginnend mit Docker
Hallo Welt mit Spring Boot
Setzen Sie Cookies mit Spring Boot
REST-API-Test mit REST Assured
Verwenden Sie Spring JDBC mit Spring Boot
Modul mit Spring Boot hinzufügen
API mit Spring + Vue.js verknüpfen
Einführung in Spring Boot Teil 1
Erstellen Sie mit Spring Boot einen Mikrodienst
Mail mit Spring Boot verschicken
Behandeln Sie die Java 8-Datums- und Uhrzeit-API mit Thymeleaf mit Spring Boot
Versuchen Sie, die Springcode-Such-API mit Spring Boot aufzurufen
Lassen Sie uns herausfinden, wie Sie mit Request Body mit der REST-API von Spring Boot empfangen können
Verwenden Sie die Standardauthentifizierung mit Spring Boot
Erstellen wir eine Buchverwaltungs-Webanwendung mit Spring Boot part1
gRPC auf Spring Boot mit grpc-spring-boot-Starter
Erstellen Sie eine App mit Spring Boot 2
Hot Deploy mit Spring Boot-Entwicklung
Datenbankverknüpfung mit doma2 (Spring Boot)
Lassen Sie uns mit Spring Boot part3 eine Webanwendung für die Buchverwaltung erstellen
Spring Boot: Restful API-Beispielprojekt
Spring Boot Programmierung mit VS Code
Erstellen Sie eine Anfrage-App mit Spring Boot
Teil 1: Versuchen Sie, die von Spring Security 5 unterstützte OAuth 2.0-Anmeldung mit Spring Boot zu verwenden
So erstellen Sie mit Spring Boot einen eigenen Controller, der / error entspricht
Lassen Sie uns mit Spring Boot part2 eine Webanwendung für die Buchverwaltung erstellen
Erhalten Sie Validierungsergebnisse mit Spring Boot
Spring Boot Access Authorization RESTful API
Ich habe ein einfaches Suchformular mit Spring Boot + GitHub Search API erstellt.
(Intellij) Hallo Welt mit Spring Boot
Erstellen Sie eine App mit Spring Boot