Java Spring Boot 如何做全局异常处理

平时开发Java后端接口时,是不是经常遇到这种情况?用户提交的信息格式不对,或者数据库查不到数据,返回给前端的却是一大串看不懂的报错代码,比如“500 Internal Server Error”“NullPointerException”,连前端都没法正常展示给用户,还得反复找开发改。这时候就需要一个好用的工具来统一处理这些异常,避免乱码一样的报错,这个工具就是Spring Boot的全局异常处理。

什么是全局异常处理?

简单说,全局异常处理就是给整个Spring Boot项目装一个“报错过滤器”,不管是哪个接口抛出的异常,都会被这个过滤器接住,然后统一整理成清晰的格式返回给前端,比如“用户名不能为空”“密码长度要在6-20位之间”,前端能直接展示给用户,也方便开发排查问题,不用再挨个接口写try-catch抓异常。

Java Spring Boot 如何做全局异常处理

举个生活化的例子:你开了个奶茶店,客人点单时要奶茶、甜度、冰度,要是客人没选甜度,或者选了不存在的冰度,前台的服务员(对应项目的接口)不用自己处理“客人信息不对”的问题,而是统一把这种“异常情况”交给店长(全局异常处理器),店长会按统一规则告诉客人:“您的甜度选项未填写哦”,而不是随便甩一句“出错了”。

第一步:定义统一的返回格式

既然要统一返回,得先定好一个大家都认可的格式,不然前端还是不知道怎么解析。比如我们约定返回三个内容:

  • code:状态码,比如成功是200,参数不对是400,服务器内部错是500
  • msg:提示信息,给用户看的清晰内容
  • data:返回的数据,出错时可以为空

就像奶茶店的点单反馈:成功下单返回“code:200, msg:下单成功, data:订单号”;没选甜度返回“code:400, msg:甜度选项未填写”,这样双方都清楚。

第二步:编写全局异常处理类

接下来就是把这个“过滤器”做出来,用Spring Boot提供的@RestControllerAdvice注解,专门用来做全局的异常处理。

举个实际的小例子,我们写一个异常处理类:

  • 先加@RestControllerAdvice,告诉Spring这是全局异常处理的类;
  • 写专门处理参数校验错误的方法,比如用@Valid校验用户提交的参数,要是用户没填用户名,这个方法就会接住,返回“用户名不能为空”;
  • 再写处理业务异常的方法,比如订单不存在,返回“您查询的订单不存在”;
  • 最后写处理其他未知异常的方法,比如服务器抽风了,返回“系统繁忙,请稍后再试”,同时把具体错误记到日志里,方便开发排查。

还是用奶茶店举例:店长(异常处理类)有不同的应对方案——客人没选甜度(参数校验错),说“甜度选项未填写”;客人要的奶茶卖完了(业务异常),说“这款奶茶暂时售罄”;要是突然停电了(未知异常),就说“系统繁忙,请稍后再试”,同时自己记下来停电的情况(打日志)。

第三步:测试效果

写完之后要试试有没有用,比如写一个注册接口,要求用户名不能少于2位,密码不能少于6位,用@Valid做校验。要是用户提交的用户名只有1位,原本会返回一堆Java报错,现在经过全局异常处理,会直接返回{"code":400,"msg":"用户名长度不能少于2位","data":null},清晰明了。

最后提醒

全局异常处理不是越复杂越好,别把业务逻辑都塞进去,只负责统一处理异常和返回格式就好。另外,要把具体的技术错误(比如代码里的空指针)藏在日志里,不要直接返回给前端,避免泄露项目的技术细节,影响安全。

这样一套流程下来,不管项目里有多少接口,异常都能被统一处理,不用反复写try-catch,既省时间又规范了报错格式,不管是给用户看还是给开发自己排查问题,都方便很多。

上一篇 C / C++ 语言核心特性与应用场景的全方位知识科普