Lorsqu'une erreur se produit, elle s'affiche sous la forme 404 Not Found.
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;
/**
*Contrôleur d'erreur pour l'ensemble de l'application Web.
*Classe d'implémentation d'interface ErrorController.
*/
@Controller
@RequestMapping("/error") //Mappage vers la page d'erreur
public class MySimpleErrorController implements ErrorController {
/**
*Renvoie le chemin de la page d'erreur.
*
* @return Chemin de la page d'erreur
*/
@Override
public String getErrorPath() {
return "/error";
}
/**
*Renvoie un objet ModelAndView pour la réponse.
*
* @param req demande d'informations
* @informations de réponse param mav
* @Objet ModelAndView pour la réponse HTML de retour
*/
@RequestMapping
public ModelAndView error(HttpServletRequest req, ModelAndView mav) {
//404 introuvable pour une erreur
//Le code du stator et le contenu de sortie peuvent être personnalisés selon les besoins.
mav.setStatus(HttpStatus.NOT_FOUND);
//Spécifiez le nom de la vue
//Modèle Thymeleaf src/main/resources/templates/error.Utilisez 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 est maintenant renvoyé au client au lieu de 500 Internal Server Error etc. lorsqu'une erreur se produit. Il renvoie également désormais HTML au lieu de JSON pour l'accès à partir de clients machine tels que curl.
$ 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>
Créez des informations d'erreur détaillées afin de pouvoir sélectionner les éléments à renvoyer au client et les afficher dans le journal.
La classe DefaultErrorAttributes de Spring Boot facilite la création d'informations détaillées sur les erreurs.
DefaultErrorAttributes (Spring Boot Docs 2.2.1.RELEASE API)
Default implementation of ErrorAttributes. Provides the following attributes when possible:
・ Horodatage - L'heure à laquelle les erreurs ont été extraites ・ Statut - Le code d'état ・ Erreur - La raison de l'erreur ・ Exception - Le nom de classe de l'exception racine (si configuré) ・ Message - Le message d'exception ・ Erreurs - Tout objet ObjectErrors d'une exception BindingResult ・ Trace - La trace de pile d'exceptions ・ Chemin - Le chemin de l'URL lorsque l'exception a été déclenchée
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;
/**
*Contrôleur d'erreur pour l'ensemble de l'application Web.
*Classe d'implémentation d'interface ErrorController.
*/
@Controller
@RequestMapping("/error") //Mappage vers la page d'erreur
public class MyDetailErrorController implements ErrorController {
/**
*Renvoie le chemin de la page d'erreur.
*
* @return Chemin de la page d'erreur
*/
@Override
public String getErrorPath() {
return "/error";
}
/**
*Extraire les informations d'erreur.
*
* @param req demande d'informations
* @renvoyer les informations d'erreur
*/
private static Map<String, Object> getErrorAttributes(HttpServletRequest req) {
//Obtenez des informations d'erreur détaillées avec la classe DefaultErrorAttributes
ServletWebRequest swr = new ServletWebRequest(req);
DefaultErrorAttributes dea = new DefaultErrorAttributes(true);
return dea.getErrorAttributes(swr, true);
}
/**
*Déterminez l'état HTTP de la réponse.
*
* @param req demande d'informations
* @Statut HTTP pour la réponse de retour
*/
private static HttpStatus getHttpStatus(HttpServletRequest req) {
//Déterminer l'état HTTP
//Ici, tous sauf 404 sont réglés sur 500.
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;
}
/**
*Renvoie un objet ModelAndView pour la réponse HTML.
*
* @param req demande d'informations
* @informations de réponse param mav
* @Objet ModelAndView pour la réponse HTML de retour
*/
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView myErrorHtml(HttpServletRequest req, ModelAndView mav) {
//Obtenir des informations d'erreur
Map<String, Object> attr = getErrorAttributes(req);
//Déterminer l'état HTTP
HttpStatus status = getHttpStatus(req);
//Définir l'état HTTP
mav.setStatus(status);
//Spécifiez le nom de la vue
//Modèle Src pour Thymeleaf/main/resources/templates/error.html
mav.setViewName("error");
//Définissez les informations que vous souhaitez afficher
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;
}
/**
*Renvoie un objet ResponseEntity pour la réponse JSON.
*
* @param req demande d'informations
* @Objet ResponseEntity pour renvoyer la réponse JSON
*/
@RequestMapping
public ResponseEntity<Map<String, Object>> myErrorJson(HttpServletRequest req) {
//Obtenir des informations d'erreur
Map<String, Object> attr = getErrorAttributes(req);
//Déterminer l'état HTTP
HttpStatus status = getHttpStatus(req);
//Définissez les informations que vous souhaitez afficher
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"));
//Informations de sortie dans JSON
return new ResponseEntity<>(body, status);
}
}
Renvoie la valeur spécifiée dans la classe d'implémentation d'interface ErrorController.
<!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>
Un exemple de renvoi d'une erreur de serveur interne 500 en HTML. Des informations détaillées sur les erreurs sont intégrées au HTML.
$ 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)
(Ce qui suit est omis)
Un exemple de renvoi d'une erreur de serveur interne 500 dans JSON. Des informations détaillées sur l'erreur sont incluses dans le JSON.
$ 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(Omission)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