起因
这是service层的一个业务方法,业务功能是:查询某些二维码数据。可以看到我们在这个方法里面除了主要的业务逻辑
,还有数据非空判断,以及异常处理等等。
如果我们不仅仅是在service层添加try catch异常处理,在controller层调用service方法的地方也添加了try catch这样的异常处理代码,那么代码冗余严重且不易维护
总结-上诉代码存在两个问题
1、上边的代码只要操作不成功仅向用户返回“错误代码:-1,失败信息:操作失败”,无法区别具体的错误信
息。–参见第三处代码
2、service方法在执行过程出现异常在哪捕获?在service中需要都加try/catch,如果在controller也需要添加
try/catch,代码冗余严重且不易维护。
以下项目是 springboot2.0.1 下开发
解决方式
1、在Service方法中的编码顺序是先校验判断,有问题则抛出具体的异常信息,最后执行具体的业务操作,返回成
功信息。
2、在统一异常处理类中去捕获异常,无需controller捕获异常,向用户返回统一规范的响应信息。
异常处理流程
系统对异常的处理使用统一的异常处理流程:
1、自定义异常类型。
2、自定义错误代码及错误信息。
3、对于可预知的异常由程序员在代码中主动抛出,由SpringMVC统一捕获。可预知异常是程序员在代码中手动抛出本系统定义的特定异常类型,由于是程序员抛出的异常,通常异常信息比较齐全,程序员在抛出时会指定错误代码及错误信息,获取异常信息也比较方便。
4、对于不可预知的异常(运行时异常)由SpringMVC统一捕获Exception类型的异常。不可预知异常通常是由于系统出现bug、或一些不要抗拒的错误(比如网络中断、服务器宕机等),异常类型为
RuntimeException类型(运行时异常)。
5、可预知的异常及不可预知的运行时异常最终会采用统一的信息格式(错误代码+错误信息)来表示,最终也会随请求响应给客户端。
1、在controller、service、dao中程序员抛出自定义异常;springMVC框架抛出框架异常类型
2、统一由异常捕获类捕获异常,并进行处理
3、捕获到自定义异常则直接取出错误代码及错误信息,响应给用户。
4、捕获到非自定义异常类型首先从Map中找该异常类型是否对应具体的错误代码,如果有则取出错误代码和错误
信息并响应给用户,如果从Map中找不到异常类型所对应的错误代码则统一为99999错误代码并响应给用户。
5、将错误代码及错误信息以Json格式响应给用户。
特别解释
不可知异常我们在上图中有两个分支,左边的分支表示的是有些不可知异常我们是知道的(这个可能比较拗口),例如SQLException,HttpMessageNotReadableException(消息转化异常),这些异常我们是可以特别处理的,可以给其标注响应的错误信息,而不用走右边的99999默认消息异常处理分支。
实现
定义常用错误代码接口-错误信息格式
|
根据这个信息格式我们可以自定义我们的错误实现。例如通用的消息模块CommonCode里面包含了常用的错误消息例子、文件上传消息模块FileSystemCode、认证消息模块AuthCode等等。满足我们自己业务的相关提示和异常提示。
定义通用的消息模块CommonCode
|
文件上传消息模块FileSystemCode-可选
|
基础的消息格式我们已经做完了,那么接下来就是定义我们的异常
可预知异常和不可预知异常处理
(1)自定义异常类
|
(2)异常抛出类
|
(3)异常捕获类
使用 @ControllerAdvice和@ExceptionHandler注解来捕获指定类型的异常
|
测试使用
改造上诉代码,try catch语句可以去掉,而且可以返回我们精准自定义的错误信息
总结
实现的关键点在于,使用 @ControllerAdvice和@ExceptionHandler注解来捕获指定类型的异常
@ExceptionHandler
|
@ControllerAdvice 增强版控制器
|