springboot全局异常处理_Spring Boot 中的全局异常处理

56867895cc455b54a279caf83b7b9811.gif

阅读本文约需要5分钟

大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈)。上次老师跟大家分享了Spring Boot 集成 Thymeleaf 模板引擎。今天给大家分享下Spring Boot 中的全局异常处理。

在项目开发过程中,不管是对底层数据库的操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。如果对每个过程都单独作异常处理,那系统的代码耦合度会变得很高,此外,开发工作量也会加大而且不好统一,这也增加了代码的维护成本。

针对这种实际情况,我们需要将所有类型的异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能单一,也实现了异常信息的统一处理和维护。同时,我们也不希望直接把异常抛给用户,应该对异常进行处理,对错误信息进行封装,然后返回一个友好的信息给用户。本节课主要总结一下项目中如何使用 Spring Boot 拦截并处理全局的异常。

1. 定义返回的统一 JSON 结构

前端或者其他服务请求本服务的接口时,该接口需要返回对应的 JSON 数据,一般该服务只需要返回请求中需要的参数即可。但在实际项目中,我们需要封装更多的信息,比如状态码 code、相关信息 msg 等等,一方面是在项目中可以有个统一的返回结构,整个项目组都适用,另一方面方便结合全局异常处理信息,因为一般在异常处理信息中我们需要把状态码和异常内容反馈给调用方。

ef26ca2aed4b6051fd487d1a41486121.png

2. 处理系统异常

新建一个 GlobalExceptionHandler 全局异常处理类,然后加上 @ControllerAdvice 注解即可拦截项目中抛出的异常,如下代码:

2bc1c3fa7fddadb0aa5dd0339c78a658.png

我们点开 @ControllerAdvice 注解可以看到,@ControllerAdvice 注解包含了 @Component 注解,说明在 Spring Boot 启动时,也会把该类作为组件交给 Spring 来管理。

除此之外,该注解还有个 basePackages 属性,该属性用来拦截哪个包中的异常信息,一般我们不指定这个属性,我们拦截项目工程中的所有异常。@ResponseBody 注解是为了异常处理完之后给调用方输出一个 JSON 格式的封装数据。

在项目中如何使用呢?Spring Boot 中很简单,在方法上通过 @ExceptionHandler 注解来指定具体的异常,然后在方法中处理该异常信息,最后将结果通过统一的 JSON 结构体返回给调用者。下面我们举几个例子来说明如何来使用。

1)处理参数缺失异常

在前后端分离的架构中,前端请求后台的接口都是通过 REST 风格来调用,有时候,比如 POST 请求需要携带一些参数,然而有时候往往会漏掉参数。另外,在微服务架构中,涉及到多个微服务之间的接口调用时,也可能出现这种情况,此时我们需要定义一个处理参数缺失异常的方法,来给前端或者调用方提示一个友好信息。

参数缺失的时候,会抛出 HttpMessageNotReadableException,我们可以拦截该异常,做一个友好处理,如下代码:

30459a7810b9e6e96a7872d34a448f0d.png

2)处理空指针异常

空指针异常是开发中司空见惯的东西了,一般发生的地方有哪些呢?

先来聊一聊一些需要注意的地方,比如在微服务中,经常会调用其他服务获取数据,这个数据主要是 JSON 格式的,但是在解析 JSON 的过程中,可能会有空内容的出现,所以我们在获取某个 jsonObject 时,再通过该 jsonObject 去获取相关信息时,应该要先做非空判断。

还有一个很常见的地方就是从数据库中查询的数据,不管是查询一条记录封装在某个对象中,还是查询多条记录封装在一个 List 中,我们接下来都要去处理数据,那么就有可能出现空指针异常,因为谁也不能保证从数据库中查出来的东西就一定不为空,所以在使用数据时一定要先做非空判断。

对空指针异常的处理很简单,和上面的逻辑一样,将异常信息换掉即可。如下代码:

ba86e2dcf82556fe9976a4fa8e7cf090.png

3)一劳永逸?

当然了,异常很多,比如还有 RuntimeException,数据库还有一些查询或者操作异常等等。由于 Exception 异常是父类,所有异常都会继承该异常,所以我们可以直接拦截 Exception 异常,一劳永逸:

20b9b25926240e68e56c78ce83ecd265.png

但在项目中,我们一般都会比较详细地去拦截一些常见异常,拦截 Exception 虽然可以一劳永逸,但是不利于我们去排查或者定位问题。实际项目中,可以把拦截 Exception 异常写在 GlobalExceptionHandler 最下面,如果都没有找到,最后再拦截一下 Exception 异常,保证输出信息友好。

今天就分享到这,今日留言话题:Springboot中全局异常处理你学会了吗?对有价值的留言,我们都会一一回复的。如果觉得对你有一丢丢帮助,请点右下角【在看】,让更多人看到该文章。

【我们直招】很苦逼,但工资超级高!

487d78574ca3ba51b0ce9bc15f2be85f.gif

33f0a358f3b1f58530670d013bf64b67.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值