--Spring Boot-Standardeinstellungen geben Whitelabel-Fehlerseite und JSON zurück, wenn 404 Not Found oder 500 Internal Server Error auftritt --HTML wird für den Zugriff über einen Webbrowser zurückgegeben --JSON wird für den Zugriff von Maschinenclients wie Curl zurückgegeben
Wenn ein Fehler auftritt, wird er als 404 Not Found angezeigt.
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
*Fehlercontroller für die gesamte Webanwendung.
*Implementierungsklasse der ErrorController-Schnittstelle.
*/
@Controller
@RequestMapping("/error") //Zuordnung zur Fehlerseite
public class MySimpleErrorController implements ErrorController {
/**
*Gibt den Pfad der Fehlerseite zurück.
*
* @Rückgabe des Fehlerseitenpfads
*/
@Override
public String getErrorPath() {
return "/error";
}
/**
*Gibt ein ModelAndView-Objekt für die Antwort zurück.
*
* @param req Anforderungsinformationen
* @param mav Antwortinformationen
* @ModelAndView-Objekt für die Rückgabe einer HTML-Antwort
*/
@RequestMapping
public ModelAndView error(HttpServletRequest req, ModelAndView mav) {
//404 Für keinen Fehler gefunden
//Der Statorcode und der Ausgabeinhalt können nach Bedarf angepasst werden.
mav.setStatus(HttpStatus.NOT_FOUND);
//Geben Sie den Namen der Ansicht an
//Thymeleaf Vorlage src/main/resources/templates/error.Verwenden Sie HTML
mav.setViewName("error");
return mav;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404 Not Found</title>
</head>
<body>
<h1>404 Not Found</h1>
</body>
</html>
404 Not Found wird jetzt an den Client zurückgegeben, anstatt 500 Internal Server Error usw., wenn ein Fehler auftritt. Es gibt jetzt auch HTML anstelle von JSON für den Zugriff von Maschinenclients wie Curl zurück.
$ curl --include http://localhost:8080/
HTTP/1.1 404
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: text/html;charset=UTF-8
Content-Language: ja-JP
Transfer-Encoding: chunked
Date: Mon, 18 Nov 2019 13:33:52 GMT
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404 Not Found</title>
</head>
<body>
<h1>404 Not Found</h1>
</body>
</html>
Erstellen Sie detaillierte Fehlerinformationen, damit Sie auswählen können, was an den Client zurückgegeben werden soll, und diese im Protokoll ausgeben können.
Mit der DefaultErrorAttributes-Klasse von Spring Boot können auf einfache Weise detaillierte Fehlerinformationen erstellt werden.
DefaultErrorAttributes (Spring Boot Docs 2.2.1.RELEASE API)
Default implementation of ErrorAttributes. Provides the following attributes when possible:
・ Zeitstempel - Die Zeit, zu der die Fehler extrahiert wurden ・ Status - Der Statuscode ・ Fehler - Der Fehlergrund ・ Ausnahme - Der Klassenname der Stammausnahme (falls konfiguriert) ・ Nachricht - Die Ausnahmemeldung ・ Fehler - Alle ObjectErrors aus einer BindingResult-Ausnahme ・ Trace - Der Exception-Stack-Trace ・ Pfad - Der URL-Pfad, als die Ausnahme ausgelöst wurde
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
*Fehlercontroller für die gesamte Webanwendung.
*Implementierungsklasse der ErrorController-Schnittstelle.
*/
@Controller
@RequestMapping("/error") //Zuordnung zur Fehlerseite
public class MyDetailErrorController implements ErrorController {
/**
*Gibt den Pfad der Fehlerseite zurück.
*
* @Rückgabe des Fehlerseitenpfads
*/
@Override
public String getErrorPath() {
return "/error";
}
/**
*Fehlerinformationen extrahieren.
*
* @param req Anforderungsinformationen
* @Fehlerinformationen zurückgeben
*/
private static Map<String, Object> getErrorAttributes(HttpServletRequest req) {
//Detaillierte Fehlerinformationen erhalten Sie mit der DefaultErrorAttributes-Klasse
ServletWebRequest swr = new ServletWebRequest(req);
DefaultErrorAttributes dea = new DefaultErrorAttributes(true);
return dea.getErrorAttributes(swr, true);
}
/**
*Bestimmen Sie den HTTP-Status für die Antwort.
*
* @param req Anforderungsinformationen
* @HTTP-Status für die Rückantwort
*/
private static HttpStatus getHttpStatus(HttpServletRequest req) {
//Bestimmen Sie den HTTP-Status
//Hier sind alle außer 404 auf 500 eingestellt.
Object statusCode = req.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
if (statusCode != null && statusCode.toString().equals("404")) {
status = HttpStatus.NOT_FOUND;
}
return status;
}
/**
*Gibt ein ModelAndView-Objekt für die HTML-Antwort zurück.
*
* @param req Anforderungsinformationen
* @param mav Antwortinformationen
* @ModelAndView-Objekt für die Rückgabe einer HTML-Antwort
*/
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView myErrorHtml(HttpServletRequest req, ModelAndView mav) {
//Fehlerinformationen abrufen
Map<String, Object> attr = getErrorAttributes(req);
//Bestimmen Sie den HTTP-Status
HttpStatus status = getHttpStatus(req);
//Legen Sie den HTTP-Status fest
mav.setStatus(status);
//Geben Sie den Namen der Ansicht an
//Src für Thymeleaf Vorlage/main/resources/templates/error.html
mav.setViewName("error");
//Legen Sie die Informationen fest, die Sie ausgeben möchten
mav.addObject("status", status.value());
mav.addObject("timestamp", attr.get("timestamp"));
mav.addObject("error", attr.get("error"));
mav.addObject("exception", attr.get("exception"));
mav.addObject("message", attr.get("message"));
mav.addObject("errors", attr.get("errors"));
mav.addObject("trace", attr.get("trace"));
mav.addObject("path", attr.get("path"));
return mav;
}
/**
*Gibt ein ResponseEntity-Objekt für die JSON-Antwort zurück.
*
* @param req Anforderungsinformationen
* @ResponseEntity-Objekt für die Rückgabe der JSON-Antwort
*/
@RequestMapping
public ResponseEntity<Map<String, Object>> myErrorJson(HttpServletRequest req) {
//Fehlerinformationen abrufen
Map<String, Object> attr = getErrorAttributes(req);
//Bestimmen Sie den HTTP-Status
HttpStatus status = getHttpStatus(req);
//Legen Sie die Informationen fest, die Sie ausgeben möchten
Map<String, Object> body = new HashMap();
body.put("status", status.value());
body.put("timestamp", attr.get("timestamp"));
body.put("error", attr.get("error"));
body.put("exception", attr.get("exception"));
body.put("message", attr.get("message"));
body.put("errors", attr.get("errors"));
body.put("trace", attr.get("trace"));
body.put("path", attr.get("path"));
//Informationen in JSON ausgeben
return new ResponseEntity<>(body, status);
}
}
Gibt den in der Implementierungsklasse der ErrorController-Schnittstelle angegebenen Wert aus.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>/error</title>
</head>
<body>
<div th:text="'timestamp: ' + ${timestamp}"></div>
<div th:text="'status: ' + ${status}"></div>
<div th:text="'error: ' + ${error}"></div>
<div th:text="'exception: ' + ${exception}"></div>
<div th:text="'message: ' + ${message}"></div>
<div th:text="'errors: ' + ${errors}"></div>
<div th:text="'trace: ' + ${trace}"></div>
<div th:text="'path: ' + ${path}"></div>
</body>
</html>
Ein Beispiel für die Rückgabe eines 500 Internal Server Error in HTML. Detaillierte Fehlerinformationen sind in HTML eingebettet.
$ curl --include -H "accept: text/html" http://localhost:8080/sample
HTTP/1.1 500
Content-Type: text/html;charset=UTF-8
Content-Language: ja-JP
Transfer-Encoding: chunked
Date: Mon, 18 Nov 2019 13:55:21 GMT
Connection: close
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>/error</title>
</head>
<body>
<div>timestamp: Mon Nov 18 22:55:21 JST 2019</div>
<div>status: 500</div>
<div>error: Internal Server Error</div>
<div>exception: java.lang.RuntimeException</div>
<div>message: This is a sample exception.</div>
<div>errors: null</div>
<div>trace: java.lang.RuntimeException: This is a sample exception.
at com.example.demo.DemoApplication.index(DemoApplication.java:18)
(Folgendes wird weggelassen)
Ein Beispiel für die Rückgabe eines 500 Internal Server Error in JSON. Detaillierte Fehlerinformationen sind im JSON enthalten.
$ curl --include http://localhost:8080/sample
HTTP/1.1 500
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 18 Nov 2019 13:55:31 GMT
Connection: close
{"exception":"java.lang.RuntimeException","path":"/sample","trace":"java.lang.RuntimeException: This is a sample exception.\n\tat com.example.demo.DemoApplication.index(DemoApplication.java:18)\n\t(Unterlassung)java.base/java.lang.Thread.run(Thread.java:834)\n","error":"Internal Server Error","message":"This is a sample exception.","errors":null,"status":500,"timestamp":"2019-11-18T13:55:31.644+0000"}
Recommended Posts