Grundidee
Erste Option ist Fehlerobjekte zu definieren und sie als 404 Not Found
Körper zurückzukehren. So etwas wie folgt vor:
Map<String, String> errors = ....;
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errors);
Statt einen typischen ResponseEntity
zurückzukehren, können Sie einen Exception
werfen, die zu einem 404 Not Found
gelöst werden. Angenommen, Sie haben ein NotFoundException
wie:
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {}
Dann, wenn Sie diese Ausnahme in Ihre Controller werfen, würden Sie so etwas wie sehen:
{
"timestamp":1461621047967,
"status":404,
"error":"Not Found",
"exception":"NotFoundException",
"message":"No message available",
"path":"/greet"
}
Wenn Sie anpassen möchten die Nachricht und andere Teile des Körpers, Sie sollten einen ExceptionHandler
für NotFoundException
definieren.
Einführung in Ausnahmehierarchien
Wenn Sie eine RESTful-API erstellen möchten und verschiedene Fehlercodes haben und Fehlermeldungen für verschiedene Ausnahmefällen können Sie eine Hierarchie von Ausnahmen erstellen die Vertreter Fälle und extrahieren Sie Nachricht und Code von jedem.
Zum Beispiel können Sie eine Ausnahme einführen, sagen wir APIException
, die Superklasse aller anderen Ausnahmen ist, die von Ihren Controllern ausgelöst werden. Diese Klasse definiert einen Code/Nachrichtenpaar wie:
public class APIException extends RuntimeException {
private final int code;
private final String message;
APIException(int code, String message) {
this.code = code;
this.message = message;
}
public int code() {
return code;
}
public String message() {
return message;
}
}
Jede Unterklasse von der Art seiner Ausnahme je können einige sinnvolle Werte für dieses Paar liefern.
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public class InvalidStateException extends APIException {
public InvalidStateException() {
super(1, "Application is in invalid state");
}
}
Oder dass berüchtigt nicht gefunden diejenigen: Zum Beispiel könnten wir eine InvalidStateException
haben
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public class SomethingNotFoundException extends APIException {
public SomethingNotFoundException() {
super(2, "Couldn't find something!");
}
}
Dann sollten wir eine ErrorController
definieren, die diese Ausnahmen und machen sie zu sinnvollen JSON Darstellungen fängt. Dieser Fehler Controller aussehen kann wie folgt vor:
@RestController
public class APIExceptionHandler extends AbstractErrorController {
private static final String ERROR_PATH = "/error";
private final ErrorAttributes errorAttributes;
@Autowired
public APIExceptionHandler(ErrorAttributes errorAttributes) {
super(errorAttributes);
this.errorAttributes = errorAttributes;
}
@RequestMapping(path = ERROR_PATH)
public ResponseEntity<?> handleError(HttpServletRequest request) {
HttpStatus status = getStatus(request);
Map<String, Object> errors = getErrorAttributes(request, false);
getApiException(request).ifPresent(apiError -> {
errors.put("message" , apiError.message());
errors.put("code", apiError.code());
});
// If you don't want to expose exception!
errors.remove("exception");
return ResponseEntity.status(status).body(errors);
}
@Override
public String getErrorPath() {
return ERROR_PATH;
}
private Optional<APIException> getApiException(HttpServletRequest request) {
RequestAttributes attributes = new ServletRequestAttributes(request);
Throwable throwable = errorAttributes.getError(attributes);
if (throwable instanceof APIException) {
APIException exception = (APIException) throwable;
return Optional.of(exception);
}
return Optional.empty();
}
}
Also, wenn Sie einen SomethingNotFoundException
werfen, würde die zurück JSON wie:
{
"timestamp":1461621047967,
"status":404,
"error":"Not Found",
"message":"Couldn't find something!",
"code": 2,
"path":"/greet"
}
Vielen Dank Ali, aber auf diese Weise kann ich die Nachricht nicht definieren. Ich habe versucht, die Ursache Eigenschaft wie in @ResponseStatus (Wert = HttpStatus.NOT_FOUND, Grund = "Ressource nicht gefunden") hinzufügen, aber dann ist die Antwort so etwas wie {"Nachricht": "error.404", "Beschreibung": "Ressource nicht gefunden“, "fieldErrors": null} – luso
Durch die Art, wie ich es auf diese Weise werfen Rückkehr Optional.ofNullable (entity) .map (Ergebnis -> neues ResponseEntity <> ( Ergebnis HttpStatus.OK)) .orElseThrow (HTTPNotFoundException :: new); – luso
Vielleicht hilft update ... –