Ich möchte die Standardfehlermeldung steuern, die zurückgegeben wird, wenn ein Fehler in der von Spring Boot erstellten REST-API auftritt.
Angenommen, Sie haben den folgenden RestController vorbereitet.
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(); //Erwartete Ausnahme
}
return "Hello world!!";
}
@RequestMapping(value="/test-null")
private String hello(){
String s = null;
s.equals("hoge"); //Versehentlicher NPE-Ausbruch
return "Hello world!!";
}
}
Spring Boot gibt dann standardmäßig die folgende Fehlermeldung zurück.
$ curl http://localhost:8080/test/0000 #Erwarteter MyCustomError
{"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, die ich versehentlich gelöscht habe
{"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 #Falscher Pfad
{"timestamp":1526654639289,"status":404,"error":"Not Found","message":"No message available","path":"/wrong-path"}%
Es ist jedoch zu cool und für die Sicherheit nicht gut, die NullPointerException zu sehen, die dem Benutzer versehentlich passiert ist. Ich bin auch mit Spring Boot konfrontiert.
Durch Vorbereiten einer Klasse mit der Annotation "@ ControllerAdvice" ist es möglich, Fehlermeldungen über RestController hinweg zu steuern.
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 {
/**
*Handler, wenn MyCustomException auftritt
*
* @Antwort zurückgeben
*/
@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.%
Wenn Sie einen ExceptionHandler erstellen, der Exception.class empfängt, können Sie außerdem eine benutzerdefinierte Fehlermeldung einheitlich für jeden unerwarteten Fehler zurückgeben, der in RestController auftritt.
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 {
/**
*Handler, wenn MyCustomException auftritt
*
* @Antwort zurückgeben
*/
@ExceptionHandler(MyCustomException.class)
public ResponseEntity<String> handleControllerException() {
return new ResponseEntity<String>("customized message for MyCustomError.", HttpStatus.INTERNAL_SERVER_ERROR);
}
/**
*Handler, wenn eine Ausnahme auftritt
*
* @Antwort zurückgeben
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleControllerException2() {
return new ResponseEntity<String>("customized message for any unexpected exception.", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Diese Methode steuert jedoch keine Fehler vor der Eingabe von RestController, z. B. falsche Pfade.
$ 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 #Ein Standardfehler wird für einen falschen Pfad zurückgegeben
{"timestamp":1526655182855,"status":404,"error":"Not Found","message":"No message available","path":"/wrong-path"}%
Als ich es nachgeschlagen habe, war es [Official](https://docs.spring.io/spring-boot/docs/1.5.3.RELEASE/reference/html/boot-features-developing-web-applications.html#boot-features -Fehlerbehandlung) hat die folgende Beschreibung.
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.
Der Punkt ist, dass jeder Fehler standardmäßig unter "/ error" abgebildet wird. Wenn Sie es nach Belieben steuern möchten, realisieren Sie ErrorController, und bereiten Sie die folgende Klasse vor.
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";
}
}
Dann verschwand die Standardfehlermeldung.
$ 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.%