SpringBoot如何优雅地处理全局异常详解
作者:Coder小明 发布时间:2023-01-06 04:30:19
前言
之前用springboot的时候,只知道捕获异常使用try{}catch,一个接口一个try{}catch,这也是大多数开发人员异常处理的常用方式,虽然屡试不爽,但会造成一个问题,就是一个Controller下面,满屏幕的try{}catch,看着一点都不优雅,一点都不符合小明的气质,憋了这么久,小明今天终于决定对所有异常实施统一处理的方案。
开发准备
JDK8、正常的springboot项目
代码编写
通用异常处理
其实Spring系列的项目全局异常处理方式早已存在,只不过我们一直忙于搬砖,很少停下脚步去审视这个日夜与我们相伴的朋友。为了贴合主题,本次主要针对SpringBoot全局异常处理进行举例说明。
SpringBoot中有一个@ControllerAdvice的注解,使用该注解即表示开启全局异常捕获,接下来我们只需在自定义的方法上使用@ExceptionHandler注解,并定义捕获异常的类型,对这种类型的异常进行统一的处理。
举个例子:
假如我们需要针对NullException(空指针异常,是Java程序员最痛恨的异常,没有之一)进行全局处理(如下所示)。
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理空指针的异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value =NullPointerException.class)
public BaseResponseFacade exceptionHandler(HttpServletRequest req, NullPointerException e){
log.error("发生空指针异常!原因是:",e);
return ResponseUtil.error(ResponseCode.ERROR);
}
}
讷,就这么简单。其他可能发生的异常,都可以以这种方式处理快速处理。此处大家应该表现的十分兴奋,但请不要高兴太早,因为接下来,有更令激动人心的事情。
自定义异常处理
自定义一个异常
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @Description 自定义异常
* @Date 2019-08-05 15:49
* @Created by 程序员小明
*/
@Data
@AllArgsConstructor
@Accessors(chain = true)
public class BizException extends RuntimeException {
/**
* 错误码
*/
protected Integer errorCode;
/**
* 错误信息
*/
protected String errorMsg;
}
显而易见,这个异常继承了RuntimeException,属于运行时异常。细心的朋友已经发现,我使用了Lombok插件,非常契合今天的主题,给大家简单介绍一下:
lombok是一个可以帮助我们简化java代码编写的工具类,尤其是简化javabean的编写,即通过采用注解的方式,消除代码中的构造方法,getter/setter等代码,使我们写的类更加简洁(如果使用的IDE是idea,需要安装插件哈)。
定义过之后,我们就可以和之前处理NullException方式一样处理我们自定义的异常。包括处理其他异常,都是这种方式。直接贴代码。
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理自定义的业务异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = BizException.class)
public BaseResponseFacade bizExceptionHandler(HttpServletRequest req, BizException e){
log.error("发生业务异常!原因是:{}",e.getErrorMsg());
return ResponseUtil.error(e.getErrorCode(),e.getErrorMsg());
}
/**
* 处理空指针的异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value =NullPointerException.class)
public BaseResponseFacade exceptionHandler(HttpServletRequest req, NullPointerException e){
log.error("发生空指针异常!原因是:",e);
return ResponseUtil.error(ResponseCode.ERROR);
}
/**
* 处理其他异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value =Exception.class)
public BaseResponseFacade exceptionHandler(HttpServletRequest req, Exception e){
log.error("未知异常!原因是:",e);
return ResponseUtil.error(ResponseCode.INTERNAL_SERVER_ERROR);
}
}
整个全局异常处理方式核心就是以上介绍这些。下面用一个Demo给大家举个例子
@GetMapping("/test")
public BaseResponseFacade test(){
if(true){
throw new BizException(1,"error");
}
return ResponseUtil.success();
}
地址栏请求,进入这个方法后,会抛出异常,此时全局异常生效,就会返回异常处理过后的信息
{"errorCode":1,"errorMsg":"error","data":null}
到此整个流程都然跑通了。当然,好多地方都可以根据我们自身实际业务情况以此为基础进一步丰富,比如返回数据可以改成跳转某一个具体的页面。这样的出场方式是不是都很优雅?
来源:https://www.cnblogs.com/coderxx/p/11331855.html


猜你喜欢
- 废话不多说了,先给大家上左右无限滑动的代码了。1.左右无限滑动public class MainActivity extends AppCo
- 本文实例为大家分享了android实现注册登录程序的具体代码,供大家参考,具体内容如 * 册页面:user_register.xml:<
- 看过阿里巴巴开发手册的同学应该都会对Integer临界值127有点印象。原文中写的是:【强制】所有整型包装类对象之间值的比较,全部使用 eq
- 配置如下: <!--邀请用户送优惠券规则{邀请人规则:[{邀请人:优惠券ID}],使用邀请码人:优惠券ID},按照邀请人数从小到大配置
- using System;namespace Partial{ class Program { &nb
- 本文实例分析了win7中C#的winForm编程使用savefiledialog不能弹出保存窗体的解决方法。分享给大家供大家参考。具体分析如
- 题目要求为:卡拉兹(Callatz)猜想:对任何一个自然数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样
- 本课程的目标是帮你更有效的使用Java。其中讨论了一些高级主题,包括对象的创建、并发、序列化、反射以及其他高级特性。本课程将为你的精通Jav
- 阅读Dubbo源码过程中,会发现,Dubbo消费端在做远程调用时,默认通过 Javassist 框架为服务接口生成 * 类,调用javas
- Java中java.io包为我们提供了输入流和输出流,对文件的读写基本上都依赖于这些封装好的关于流的类中来实现。前段时间遇到了以下两种需求:
- 虹软免费,高级版本试用支持在线、离线有 Java SDK,C++ SDK一、注册虹软开发者平台点击注册注册完成后可在“我
- 二进制、八进制和十六进制向十进制转换都是非常容易的,就是“按权相加”。所谓“权”,也即“位权”。例如,十进制第1位的位权为100=1,第2位
- 最大公约数:指两个或多个整数共有约束中最大的一个。最小公倍数:如果有一个自然数a能被自然数b整除,则称a为b的倍数,b为a的约数,对于两个整
- 想要制作一个简易的登录界面非常容易,总体上来说就是UI布局、给定id、新建跳转的页面、以及输入账号密码的获取与判断,那么接下来就开始制作吧!
- 前言上一篇文章分享了Springboot项目快速实现过滤器功能,本篇文章接着来盘一盘 * ,仔细研究后会发现,其实 * 和过滤器的功能非常类
- springBoot项目启动多个实例今天碰到一个需求是,将一个服务提供者启动两个实例,一个实例对外,一个实例对内,对内价格有折扣,两个实例通
- 本文实例为大家分享了Android封装MVP实现登录注册功能,供大家参考,具体内容如下model包:import com.bwei.mvps
- 本文实例讲述了Android编程实现系统重启与关机的方法。分享给大家供大家参考,具体如下:最近在做个东西,巧合碰到了sharedUserId
- 代码优化细节 1、尽量指定类、方法的final修饰符带有final修饰符的类是不可派生的。在Java核心API中,有许多应用fin
- springcloud eureka切换nacos配置中心地址: http://10.166.9.7:8848/nacos/bootstra