Spring Boot 统一功能处理(三)

本篇主要介绍Spring Boot的统一异常处理。

目录

一、统一异常处理的使用

二、测试统一异常处理效果

三、浅析原理

@ControllerAdvice简析

统一处理异常简析


一、统一异常处理的使用

在前面介绍统一数据返回时,我们在程序发生异常时会把整个报错信息都封装在data里返回给前端,这显然是不太合适的,毕竟让懂后端的前端看到这些具体的报错信息还挺羞耻的,因此我们来看一下如何对异常进行统一处理。

首先我们需要创建统一处理异常的类,并加上@ControllerAdvice注解:

接下来我们需要自己定义一个处理异常的具体方法handler,其参数为需要处理的异常,并在方法上加上@ExceptionHandler注解:

如果需要处理多个异常,则可以重载handler方法:

定义完这些方法之后,当我们的程序发生异常时则会自动执行这里对应的handler方法来进行统一的异常处理,并将handler的返回结果写到响应数据里,但由于Spring默认是返回Html,因此我们还需要在方法或者类上加上@RespondyBody注解来调整返回数据类型。

二、测试统一异常处理效果

接下来我们来测试一下统一异常处理的效果:

在Controller里,定义两个test方法,并分别制造一个异常,一个为空指针异常,一个为算术异常:

然后我们再修改一下前面定义的handler,让其更加规范一点

接下来我们通过PostMan来测试一下前面定义的这两个方法:

访问test05

访问test06

通过测试结果可以发现,当由于空指针异常在我们定义的统一处理类中进行对应的实现,因此调用了参数为空指针异常的handler方法,而算术异常则没有对应实现,所以调用了以Exception为参数的handler方法来处理,因此我们可以得出结论,当发生异常时会优先去寻找与异常类型一致的handler方法来进行处理,如果没有类型一致的则会去找参数为当前异常的类型的上级(父类)的handler方法来处理,其内部具体逻辑将在下文介绍。

三、浅析原理

@ControllerAdvice简析

前面在介绍初始化DispatchServerlet时,提到过在初始化最后会初始化九大组件,这九大组件中有一个HandlerAdapters,初始化这个组件时会去获取所有实现了HandlerAdapt的Bean,在这些Bean中有一个叫做RequestMappingHandlerAdapt,这个Bean会获取所有加了@ControllerAdvice注解的Bean,并进行处理。

处理完后,一旦发生了这些加了@ControllerAdvice标注的Bean对应的事件,就会调用其对应的Advice方法,例如在进行统一功能处理时,如果有数据返回了,系统就会在这个里面找对应的Bean,并调用这个bean中处理返回数据的方法。

统一处理异常简析

对于统一异常的处理,还是得追溯到九大组件,在这九大组件里有一个HandlerExceptionResolvers,初始化这个组件会去获取所有实现HandlerExceptionResolvers接口的Bean,在这些Bean中,有一个叫ExceptionHandlerExceptionResolvers的Bean,这个也会去获取所有@ControllerAdvice标注的Bean

并且它会创建一个ExceptionHandlerMethondResolver。

当项目里有异常发生时 ,会通过DispathcServerlet来解析异常,而DispatchServerlet则会通过ExceptionHandlerExceptionReslover来解析异常,最后ExceptionHandlerExceptionReslover再通过这个ExceptionHandlerMethondResolve来解析异常。ExceptionHandlerMethondResolve会将异常解析到前面对应的加了@ExceptionHandler的handler方法,具体为如下这串代码。

在这个代码里,会先创建一个List metches,

然后去获取当前异常能够匹配到的所有异常类型(包括当前异常的类型及其所有父类异常的类型),

并将这些类型添加到matches里。如果在matches添加了不止一个,也就是matches.size() > 1 ,就会对matches按类型的深度进行排序(例如当前异常类型为NullpointException,那么NullpointException的深度就为0,其父类RuntimeException的深度则为1,然后以此类推,每往上一级,深度就加一),

排完序后,则会将参数为matches中第一个类型(也就是深度最小的异常类型)这种类型的加了@Exception批注的handler方法返回。最后再由其它类来执行这个方法。

所以在前面我们在前面测试test05时访问的是参数为NullpointException的handler方法,因为在访问test05时会发生空指针异常,而发生空指针异常时NullpointException的深度最小。

相关推荐
夜色呦10 分钟前
现代电商解决方案:Spring Boot框架实践
数据库·spring boot·后端
爱敲代码的小冰19 分钟前
spring boot 请求
java·spring boot·后端
Lyqfor32 分钟前
云原生学习
java·分布式·学习·阿里云·云原生
程序猿麦小七1 小时前
今天给在家介绍一篇基于jsp的旅游网站设计与实现
java·源码·旅游·景区·酒店
张某布响丸辣1 小时前
SQL中的时间类型:深入解析与应用
java·数据库·sql·mysql·oracle
喜欢打篮球的普通人1 小时前
rust模式和匹配
java·算法·rust
java小吕布1 小时前
Java中的排序算法:探索与比较
java·后端·算法·排序算法
慢生活的人。2 小时前
SpringSecurity+jwt+captcha登录认证授权总结
java·认证·rbac·权限·验证
Goboy2 小时前
工欲善其事,必先利其器;小白入门Hadoop必备过程
后端·程序员
向阳12182 小时前
LeetCode40:组合总和II
java·算法·leetcode