|
对于最新的稳定版本,请使用 Spring Framework 7.0.6! |
异常
@Controller 和 @ControllerAdvice 类可以包含
@ExceptionHandler 方法来处理控制器方法中的异常,如下例所示:
-
Java
-
Kotlin
@Controller
public class SimpleController {
// ...
@ExceptionHandler
public ResponseEntity<String> handle(IOException ex) {
// ...
}
}
@Controller
class SimpleController {
// ...
@ExceptionHandler
fun handle(ex: IOException): ResponseEntity<String> {
// ...
}
}
该异常可能与正在传播的顶层异常匹配(例如直接抛出的IOException),或者与包装异常中的嵌套原因匹配(例如IOException被包含在IllegalStateException中)。从5.3版本开始,这可以在任意原因级别进行匹配,而之前仅考虑直接原因。
对于匹配的异常类型,最好将目标异常声明为方法参数,如前面的例子所示。当多个异常方法匹配时,通常优先选择根异常匹配而不是原因异常匹配。更具体地说,ExceptionDepthComparator用于根据异常从抛出异常类型的深度对异常进行排序。
或者,注解声明可以缩小异常类型的范围以匹配,如下例所示:
-
Java
-
Kotlin
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(IOException ex) {
// ...
}
@ExceptionHandler(FileSystemException::class, RemoteException::class)
fun handle(ex: IOException): ResponseEntity<String> {
// ...
}
你甚至可以使用一个特定异常类型的列表,并带有非常通用的参数签名,如下例所示:
-
Java
-
Kotlin
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(Exception ex) {
// ...
}
@ExceptionHandler(FileSystemException::class, RemoteException::class)
fun handle(ex: Exception): ResponseEntity<String> {
// ...
}
|
根异常和原因异常匹配之间的区别可能会令人惊讶。 在显示的 行为在 |
我们通常建议你在参数签名中尽可能具体,减少根异常类型和原因异常类型之间不匹配的潜在可能性。考虑将一个多匹配方法拆分为单独的@ExceptionHandler方法,每个方法通过其签名匹配一个特定的异常类型。
在多@ControllerAdvice配置中,我们建议您在@ControllerAdvice上声明您的主要根异常映射,并指定相应的顺序。虽然优先选择根异常匹配而不是原因,但这在给定控制器或@ControllerAdvice类的方法中定义。这意味着在优先级更高的@ControllerAdvice bean上的原因匹配优先于在优先级更低的@ControllerAdvice bean上的任何匹配(例如,根异常)。
最后但并非最不重要的是,一个@ExceptionHandler方法实现可以选择通过以原始形式重新抛出给定的异常实例来退出处理。这在你只对顶级匹配或在无法静态确定的具体上下文中的匹配感兴趣的情况下很有用。重新抛出的异常会继续通过剩余的解析链传播,就像给定的@ExceptionHandler方法根本没有匹配一样。
Spring MVC 中对 @ExceptionHandler 方法的支持是基于 DispatcherServlet 级别的 HandlerExceptionResolver 机制。
方法参数
@ExceptionHandler 个方法支持以下参数:
| 方法参数 | 描述 |
|---|---|
异常类型 |
获取引发的异常。 |
|
获取引发异常的控制器方法。 |
|
通用访问请求参数以及请求和会话属性,无需直接使用Servlet API。 |
|
选择任何特定的请求或响应类型(例如, |
|
强制要求存在会话。因此,此类参数永远不会为 |
|
当前已认证的用户——如果已知,可能是特定的 |
|
请求的HTTP方法。 |
|
当前请求的本地化设置,由最具体的 |
|
与当前请求相关联的时区,由 |
|
要访问由Servlet API暴露的原始响应体。 |
|
用于访问错误响应的模型。始终为空。 |
|
|
|
对于访问任何会话属性,与作为类级别 |
|
用于访问请求属性。有关更多详细信息,请参见 |
返回值
@ExceptionHandler 方法支持以下返回值:
| 返回值 | 描述 |
|---|---|
|
返回值通过 |
|
返回值指定将完整的响应(包括HTTP头和正文)通过 |
|
要在正文中渲染包含详细信息的RFC 7807错误响应, 参见 错误响应 |
|
要在正文中渲染包含详细信息的RFC 7807错误响应, 参见 错误响应 |
|
一个视图名称,将通过 |
|
一个 |
|
Attributes to be added to the implicit model with the view name implicitly determined
through a |
|
要添加到模型中的属性,视图名称通过 请注意, |
|
要使用的视图和模型属性,以及可选的响应状态。 |
|
具有 如果上述情况都不成立,返回类型为 |
任何其他返回值 |
如果返回值不匹配上述任何一种情况,并且不是简单类型(由 BeanUtils#isSimpleProperty 确定), 默认情况下,它将被视为要添加到模型中的模型属性。如果是简单类型,则保持未解析。 |