我正在实现ResponseEntityExceptionHandler
的所有方法,因为我不希望Spring向客户端发送任何标准错误响应。有两种看似相似的方法让我有点困惑。即handleExceptionInternal
和handleException
。根据官方文件。,这两种方法的定义如下
handleException(Exception ex, WebRequest request)
Provides handling for standard Spring MVC exceptions.
handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request)
A single place to customize the response body of all exception types.
我觉得这些解释有点含糊。例如,什么可以被认为是“标准spring异常”?是否应该将handleExceptionInternal
视为一个“默认”处理程序方法,当其他任何方法都无法捕获spring异常时使用该方法?如果我错了,请纠正我。
谢谢
发布于 2020-09-20 06:20:19
handleException
方法是标准spring异常的常见异常处理程序。它的主要任务是按照http响应代码约定将这些异常映射到相应的状态代码,这很可能不会更改。例如:
HttpRequestMethodNotSupportedException -> 405
HttpMediaTypeNotSupportedException -> 415
NoHandlerFoundException -> 404
所有这些异常都是在它们的特定处理程序方法handle{ExceptionName}
中处理的,因此,如果您希望更改状态代码(或添加响应体获取详细信息),则可以重写特定的处理程序。所有这些处理程序都进一步委托给handleExceptionInternal
。
注意到的一件事是,每个handle{ExceptionName}
方法都将body
作为null传递给handleExceptionInternal
。这些方法只是返回状态代码,没有主体,这没有提供更多关于错误的详细信息。
一个常见的做法是返回一个包含详细信息的自定义错误响应主体,以便您的api使用者知道确切的错误原因。这是您可以通过创建Error
对象注入自定义主体的位置。一条简单的错误消息看起来就像。
public class ApiError {
private final int status;
private final int message;
public ApiError(int status, int message) {
this.status = status;
this.message = message;
}
// getters
}
您可以重写handleExceptionInternal
方法如下:
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
ApiError error = new ApiError(status.value(), ex.getMessage());
return super.handleExceptionInternal(ex, error, headers, status, request);
}
摘要
如果handleException
不存在,那么您需要手动将每个异常映射到相应的错误代码。如果缺少handleExceptionInternal
,那么要插入错误体,则需要覆盖每个handle{Exception}
方法。
更新
RFC用于http状态代码定义。
https://stackoverflow.com/questions/63977406
复制相似问题