spring - 在 ResponseEntityExceptionHandler 中,handleExceptionInternal 和 handleException 之间的确切区别是什么?
问题描述
我正在实现所有方法,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 mvc 异常”?并且应该handleExceptionInternal
被视为当其他方法都无法捕获弹簧异常时使用的“默认”处理程序方法?如果我错了,请纠正我。
谢谢
解决方案
handleException
方法是标准 spring mvc 异常的常见异常处理程序。它的主要任务是根据 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}
方法。
更新http 状态代码定义的
RFC。
推荐阅读
- php - 编辑配置文件laravel 7未定义变量中的错误密码更改
- go - 如何为多个环境和突变的组合生成配置
- python - Django 在 Django 模板中访问列表元素的属性
- android - 在 Flutter 中使用 android 10 活动缩放过渡
- microsoft-graph-api - 对于我的 Teams 应用在 App Studio 中收到的权限,我应该使用什么 API?
- java - 如何防止自定义视图覆盖自身?
- linux - 从命令行执行 Java Mission Control
- python - 我是 python 新手,我自己尝试将其作为个人项目。AttributeError:“NoneType”对象没有属性“get”
- python - 即使在 `try ... except` 中,asyncio.wait 也会返回异常
- xamarin - 如何在我的 xamarin 表单项目中使用 sqlite-net-pcl 设置外键