引言
异常处理方式:
我是谁——异常处理。
来自那——所有功能正常运行,但出现错误
怎么办——如何处理异常和响应客户端
异常转换响应:
@ResponseStatus注解
我是谁——Spring框架中的一个注解
用在哪——应用在控制器类或方法上
什么用——用于在控制器方法中指定HTTP响应的状态码。
指定状态码
指定一个特定的HTTP状态码,以便在方法成功执行后返回给客户端。
例如,如果您的方法成功处理了请求并返回了所需的结果,您可以使用@ResponseStatus(HttpStatus.OK)来指定成功的状态码为200。
指定可选的reason参数
除了状态码外,@ResponseStatus还可以指定一个可选的reason参数,用于提供关于响应状态的简要说明。这样做可以增加对API的可读性和理解性。
下面是一个示例:
在上面的示例中,当请求"/users/{id}"时,如果成功找到对应id的用户,将返回状态码为200的HTTP响应。
2. 异常转换为HTTP状态码:
● 最简单的异常处理方式是将异常映射到HTTP状态码,并包含在响应中。
● 下面介绍如何将异常映射为HTTP状态码。
7.3.1 将异常映射为HTTP状态码
在默认情况下,Spring会将自身的一些异常自动转换为合适的状态 码。表7. 1列出了这些映射关系。
表7.1 Spri ng的一些异常会默认映射为HTTP状态码
Spring异常 HTTP状态码
TypeMismatchException 400 - Bad Request
第一步:创建一个spittle方法
1. 检索Spittle对象:
○ 通过ID从SpittleRepository中检索Spittle对象。
○ 如果findOne()方法返回Spittle对象,则将其放入模型中,并由名为"spittle"的视图渲染到响应中。
○ 如果findOne()方法返回null,则抛出SpittleNotFoundException异常。
2. 异常处理:
○ 如果findOne()方法返回null,则抛出SpittleNotFoundException异常。
3. 后续处理:
○ SpittleNotFoundException异常需要进行处理,以便给客户端一个合适的响应。
现在就是一个简单的非检查型异常, 如下所示:
- 处理请求并处理异常:
○ 如果调用spittle()方法处理请求,并且获取的结果为空,则会抛出SpittleNotFoundException异常。
○ 默认情况下,SpittleNotFoundException会导致500状态码的响应。
○ 可以通过映射SpittleNotFoundException来改变默认行为。
2. 修改默认行为:
○ 当抛出SpittleNotFoundException异常时,表示请求的资源未找到。
○ HTTP状态码404是最准确的响应状态码。
○ 可以使用@ResponseStatus注解将SpittleNotFoundException映射为HTTP状态码404。
程序清单7.8 @ResponseStatus注解:将异常映射为特定的状态码
在引入@ResponseStatus注解之后,如果控制器方法抛出SpittleNotFound-Exception异常的话,响应将会具有404状态 码,这是因为Spittle Not Found。
7.3.2 编写异常处理的方法
程序清单7.9 在处理请求的方法中直接处理异常
程序清单7.9中并没有特别之处,它只是在Java中处理异常的基本样例。该方法可以有两个路径,每个路径会有不同的输出。
然而,saveSpittle()方法的复杂性让人感到困惑。
只关注正确的路径,异常交给其他方法处理
首先,让我们首先将saveSpittle()方法中的异常处理方法剥离掉:
可以看到,方法简单了许多。只关注正常保存Spittle的情况,所以只有一个执行路径,容易理解和测试。
处理抛出异常DuplicateSpittleException
� 流程:
● 在handleDuplicateSpittle()方法上添加@ExceptionHandler注解
● 返回一个String类型的值,指定要渲染的逻辑视图名
简化异常处理流程
● 通过提取代码创建handleDuplicateSpittle()方法
● 不需要在每个可能抛出DuplicateSpittleException的方法中添加异常处理代码
@ExceptionHandler
注解的特点
● 可以处理同一个控制器中所有处理器方法抛出的异常
作用范围
标注的方法能够处理同一个控制器类中所有处理器方法的异常,那么你可能会问有没有一种方法能够处理所有控制器中处理器方法所抛出的异常呢。
控制器通知类的异常处理
从Spring 3.2开始,我们可以将异常处理定义到控制器通知类中,以处理所有控制器中处理器方法所抛出的异常。这种方式使得异常处理更加灵活和统一。