目录
概述:
综合实例:
继承 ResponseStatusException-自定义异常类
继承 ResponseStatusException-自定义响应头信息
继承 ResponseStatusException-定制更多异常处理逻辑
继承 ResponseStatusException-根据异常发生的上下文动态改变 HTTP 状态码
概述:
- 从 Spring 5.0 开始引入
- 特别适用于 Spring WebFlux,也可以在 Spring MVC 中使用
- 使用
ResponseStatusException
可以在代码中的任何地方抛出特定的 HTTP 状态码(比如 404 NOT FOUND 或 400 BAD REQUEST)以及一个可选的错误消息 - 这个类继承自
RuntimeException
,因而它是一个不受检异常(unchecked exception),你不需要在方法签名上声明它,也不必强制捕获它 - 其主要的目的是通过编程方式控制异常以及相应的 HTTP 状态码和错误信息的返回
ResponseStatusException
类的主构造函数如下:status
:一个HttpStatus
枚举值,表示要返回的 HTTP 状态码reason
:一个表示错误详情的String
;这个消息可能会返回给客户端,所以在设置时要注意安全性和敏感信息泄露的问题cause
:引发异常的原始Throwable
对象;这不会直接发送给客户端,通常用于日志记录目的- 有几种构造函数版本,不一定全部需要传入(
reason
)或(cause
),您可以根据实际需求使用它们
综合实例:
- 下面是一个简单的例子,展示如何在控制器方法中使用
ResponseStatusException
: - 在这个例子中,当找不到给定 ID 的 item 时,会抛出
ResponseStatusException
,并且返回状态码404 NOT FOUND
以及错误信息 “Item not found” - 由于
ResponseStatusException
是RuntimeException
的子类,Spring 框架会捕捉到这个异常,并将其转换成相应的 HTTP 响应返回给客户端 - 这个机制允许开发者以非常灵活的方式处理各种各样的异常情况
继承 ResponseStatusException-自定义异常类
- 在 Spring Boot 应用程序中,
ResponseStatusException
是一个构建好的异常类,它可以被直接使用来返回特定的 HTTP 状态代码和消息 - 你可以在方法中直接抛出它,Spring 框架将负责将异常转化为对应的 HTTP 响应
- 但是如果你有特定的需求,比如希望在你的应用程序中创建一系列具有固定状态码和自定义处理逻辑的异常,你可以继承
ResponseStatusException
- 下面是一个简单的例子,定义了一个继承自
ResponseStatusException
的自定义异常类: - 在你的 Spring Boot 应用中使用自定义异常:
- 当
CustomBadRequestException
被抛出时,Spring 框架会捕捉到这个异常,并且根据异常内的信息返回一个HttpStatus.BAD_REQUEST
(400 错误码) 的 HTTP 响应给客户端,并带有 “这里是错误信息” 作为响应体中的错误描述 - 通过这种方式,你可以定义不同的自定义异常类型,来处理你应用程序中不同的错误情况,并返回合适的 HTTP 响应
继承 ResponseStatusException-自定义响应头信息
- 在继承自
ResponseStatusException
的自定义异常类中重写getResponseHeaders()
方法可以让你添加或者定制返回给客户端的 HTTP 响应头 - 默认情况下,
ResponseStatusException
没有响应头或者只有基本的响应头 - 通过重写这个方法,你可以根据你的业务逻辑需要,添加一些特殊的响应头信息
- 例如,你可能想添加一个关于错误的链接,一个特殊的错误追踪 ID,或者控制缓存的头信息
- 下面是一个例子,演示了如何在自定义异常中重写
getResponseHeaders()
方法来添加一个自定义的响应头:
- 在控制器中抛出这个自定义的
CustomBadRequestException
将会导致 Spring 框架处理这个异常,并在最终的 HTTP 响应中包含 ‘X-Custom-Error’ 这个头信息 - 使用自定义的响应头可以提供更多的上下文信息给调用者,或者用来传达非标准的、特定于应用的消息
- 这是一个扩展标准异常处理行为并高度定制异常返回信息的强大方式
- 要注意的是,你应该谨慎添加响应头,确保它们不会暴露敏感信息或者与你的 API 设计冲突
继承 ResponseStatusException-定制更多异常处理逻辑
- 在继承
ResponseStatusException
的自定义异常类中,除了getResponseHeaders()
之外,你可能会考虑重写几个其他重要的方法来进一步定制你的异常处理逻辑:
- getMessage():
重写这个方法可以让你改变异常的错误消息
这个消息通常会被用在日志中,也可能在一些情况下返回给客户端,取决于你的错误处理配置 - getStatus():
如果你想根据异常发生的上下文动态改变 HTTP 状态码,可以重写getStatus()
方法 - getCause():
如果你的自定义异常包装了另一个异常,你可以通过getCause()
方法提供原始的异常;这对于调试和错误跟踪是非常有用的 - printStackTrace() 和 getStackTrace():
这些方法可以被用来获取和打印异常的堆栈追踪
- 通常这些方法的默认实现足够用了,但如果需要的话,你可以提供更多的信息或者定制格式
- 在实际业务情况中,我们可以重写异常类的这些方法来增强错误处理的能力,例如记录额外的调试信息、创建更为详细的错误消息等
- 让我们来创建一个更切实的业务场景来展示这一点:
- 假设我们有一个在线电商平台,当用户尝试创建订单时,如果库存不足,我们希望抛出一个自定义的异常
- 在这个自定义异常中,我们可以重写
getMessage()
方法来提供更丰富的信息,并重写printStackTrace()
和getStackTrace()
方法来添加关于库存不足的特定上下文信息
在这个示例中:
getMessage()
被重写以返回一个更为详细的错误信息printStackTrace()
被重写以打印特定的业务相关错误信息getStackTrace()
被重写以添加自定义的堆栈跟踪元素,这可能对调试有帮助,显示出是在检查库存时出现了问题getStatus()
被重写以返回一个特定的HTTP状态;请注意,通常这也可以通过在抛出异常时传递不同的HttpStatus
枚举值给构造函数来实现getMessage()
被修改以增加更多的业务信息,如最后库存同步时间
通过这样重写这些方法,我们可以提供更加具体的错误状态和信息,以便在记录日志、返回给客户端、调试等方面提供有用的上下文
继承 ResponseStatusException-根据异常发生的上下文动态改变 HTTP 状态码
- 根据库存不足时的不同情况来设置不同的状态码(比如,如果只是暂时性的库存问题使用
503 Service Unavailable
,如果是产品完全下架则使用410 Gone
) - 可以在自定义异常类中添加逻辑如下:
- 在这个示例中,
chooseHttpStatus
方法基于productDiscontinued
布尔变量的值来选择不同的HTTP状态码 - 如果产品已经停产,那么使用
410 Gone
状态码;如果仅仅是暂时的库存问题,则使用503 Service Unavailable
- 如此,异常类的构造函数中传入的参数
productDiscontinued
决定了异常应该携带的HTTP状态码