基本理念
第一个选项是定义错误对象并将其作为正文返回。如下所示:404 Not Found
Map<String, String> errors = ....;
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errors);
您可以抛出一个将解析为 .假设你有一个赞:ResponseEntity
Exception
404 Not Found
NotFoundException
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {}
然后,如果在控制器中引发此异常,则会看到如下内容:
{
"timestamp":1461621047967,
"status":404,
"error":"Not Found",
"exception":"NotFoundException",
"message":"No message available",
"path":"/greet"
}
如果要自定义消息和正文的其他部分,则应为 定义一个 。ExceptionHandler
NotFoundException
引入异常层次结构
如果您正在创建 RESTful API,并希望针对不同的例外情况使用不同的错误代码和错误消息,则可以创建表示这些情况的异常层次结构,并从每个情况中提取消息和代码。
例如,您可以引入一个异常,例如,它是控制器引发的所有其他异常的超类。此类定义一个代码/消息对,如下所示:APIException
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;
}
}
每个子类根据其异常的性质可以为该对提供一些合理的值。例如,我们可以有一个 :InvalidStateException
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public class InvalidStateException extends APIException {
public InvalidStateException() {
super(1, "Application is in invalid state");
}
}
或者那个臭名昭著的未找到的:
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public class SomethingNotFoundException extends APIException {
public SomethingNotFoundException() {
super(2, "Couldn't find something!");
}
}
然后,我们应该定义一个捕获这些异常并将其转换为有意义的JSON表示形式。该错误控制器可能如下所示:ErrorController
@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();
}
}
因此,如果您抛出一个 ,返回的 JSON 将如下所示:SomethingNotFoundException
{
"timestamp":1461621047967,
"status":404,
"error":"Not Found",
"message":"Couldn't find something!",
"code": 2,
"path":"/greet"
}