Je souhaite contrôler le message d'erreur par défaut renvoyé lorsqu'une erreur se produit dans l'API REST créée par Spring Boot.
Supposons que vous ayez préparé le RestController suivant.
MyRestController.java
package demo;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyRestController {
@RequestMapping(value="/test/{id}")
private String hello(@PathVariable String id){
if ("0000".equals(id)) {
throw new MyCustomException(); //Exception attendue
}
return "Hello world!!";
}
@RequestMapping(value="/test-null")
private String hello(){
String s = null;
s.equals("hoge"); //Épidémie de NPE par inadvertance
return "Hello world!!";
}
}
Spring Boot renverra alors le message d'erreur suivant par défaut.
$ curl http://localhost:8080/test/0000 #MyCustomError attendu
{"timestamp":1526654632290,"status":500,"error":"Internal Server Error","exception":"my.spring.MySpringBootSample.MyCustomError","message":"No message available","path":"/test/0000"}%
$ curl http://localhost:8080/test-null #NPE que j'ai éteint accidentellement
{"timestamp":1526654636310,"status":500,"error":"Internal Server Error","exception":"java.lang.NullPointerException","message":"No message available","path":"/test-null"}%
$ curl http://localhost:8080/wrong-path #Mauvais chemin
{"timestamp":1526654639289,"status":404,"error":"Not Found","message":"No message available","path":"/wrong-path"}%
Cependant, il est trop cool et pas bon pour la sécurité de voir l'exception NullPointerException qui est arrivée par inadvertance à l'utilisateur. Je suis également exposé à l'utilisation de Spring Boot.
En préparant une classe avec l'annotation @ ControllerAdvice
, il est possible de contrôler les messages d'erreur dans RestController.
MyControllerAdvice.java
package demo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class MyControllerAdvice {
/**
*Gestionnaire lorsque MyCustomException se produit
*
* @réponse de retour
*/
@ExceptionHandler(MyCustomException.class)
public ResponseEntity<String> handleControllerException() {
return new ResponseEntity<String>("customized message for MyCustomError.", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
$ curl http://localhost:8080/test/0000
customized message for MyCustomError.%
En plus de ce qui précède, si vous créez un ExceptionHandler qui reçoit Exception.class, il est possible de renvoyer un message d'erreur personnalisé de manière uniforme pour toute erreur inattendue qui se produit dans RestController.
MyControllerAdvice.java
package demo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class MyControllerAdvice {
/**
*Gestionnaire lorsque MyCustomException se produit
*
* @réponse de retour
*/
@ExceptionHandler(MyCustomException.class)
public ResponseEntity<String> handleControllerException() {
return new ResponseEntity<String>("customized message for MyCustomError.", HttpStatus.INTERNAL_SERVER_ERROR);
}
/**
*Gestionnaire lorsqu'une exception se produit
*
* @réponse de retour
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleControllerException2() {
return new ResponseEntity<String>("customized message for any unexpected exception.", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Cependant, cette méthode ne contrôle pas les erreurs avant d'entrer RestController, telles que des chemins d'accès incorrects.
$ curl http://localhost:8080/test/0000
customized message for MyCustomError.%
$ curl http://localhost:8080/test-null
customized message for any unexpected exception.%
$ curl http://localhost:8080/wrong-path #Une erreur par défaut est renvoyée pour un chemin erroné
{"timestamp":1526655182855,"status":404,"error":"Not Found","message":"No message available","path":"/wrong-path"}%
Quand je l'ai recherché, c'était [Officiel](https://docs.spring.io/spring-boot/docs/1.5.3.RELEASE/reference/html/boot-features-developing-web-applications.html#boot-features -error-handling) a la description suivante.
Spring Boot provides an /error mapping by default that handles all errors in a sensible way, and it is registered as a ‘global’ error page in the servlet container.
Le fait est que chaque erreur est mappée sous / error
par défaut.
Si vous voulez le contrôler comme vous le souhaitez, réalisez ErrorController, alors préparez la classe suivante.
MyErrorController.java
package demo;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyErrorController implements ErrorController {
@RequestMapping("/error")
public ResponseEntity<String> handleError() {
return new ResponseEntity<String>("customized message for any unhandled error.", HttpStatus.INTERNAL_SERVER_ERROR);
}
@Override
public String getErrorPath() {
return "/error";
}
}
Ensuite, le message d'erreur par défaut a disparu.
$ curl http://localhost:8080/test/0000
customized message for MyCustomError.%
$ curl http://localhost:8080/test-null
customized message for any unexpected exception.%
$ curl http://localhost:8080/wrong-path
customized message for any unhandled error.%
Recommended Posts