SpringBoot优雅地实现全局异常处理的方法详解

首先,我们需要在Spring Boot项目中添加全局异常处理器。具体步骤如下:

  1. 在pom.xml文件中添加以下依赖:
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 创建一个ExceptionHandler类,用于捕获全局异常。代码如下:
@ControllerAdvice // 开启全局异常处理
public class ExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result handleException(Exception ex) {
        return new Result(ResultCode.EXCEPTION, ex.getMessage());
    }

}

在上述代码中,@ControllerAdvice注解表示开启全局异常处理,@ExceptionHandler注解表示该方法用于捕获异常,@ResponseBody注解表示返回的是JSON数据,而不是视图。

  1. 自定义异常类。为了更好地处理业务异常,可以自定义一个异常类。代码如下:
public class BizException extends RuntimeException {

    private Integer code;

    public BizException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
    }

    public Integer getCode() {
        return code;
    }
}

在上述代码中,BizException类继承了RuntimeException类,用于表示业务异常,@code注解用于存储异常码,getMessage()方法用于获取异常信息。

  1. 抛出自定义异常。在代码中,如果需要抛出自定义异常,可以通过如下方式实现:
throw new BizException(ResultCodeEnum.USER_NOT_EXIST);

上述代码表示抛出一个业务异常,其异常码为USER_NOT_EXIST。

  1. 验证异常处理器是否起作用。可以在Controller中编写测试接口,通过发送错误请求等方式验证异常处理器是否捕获到异常,并正确返回异常信息。

在以上的步骤中,我们通过自定义异常和全局异常处理器搭配使用,能够更加优雅地处理全局异常。下面,我们通过两个例子进一步深入理解。

例子1:

假设我们有一个用户服务,其中有一个查询用户信息的接口。当输入的用户ID不合法时,我们希望返回一个业务异常。

  1. 首先,在result包下新建ResultCodeEnum类,用于枚举所有异常的类型和信息。
public enum ResultCodeEnum {

    SUCCESS(200, "操作成功!"),
    USER_NOT_EXIST(1001, "用户不存在!"),
    PARAM_ERROR(1002, "参数错误!"),
    AUTH_FAILED(1003, "认证失败!"),
    EXCEPTION(9999, "系统异常,请稍后再试!");

    private Integer code;
    private String message;

    ResultCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

在上述代码中,我们枚举了所有异常的类型和信息,其中USER_NOT_EXIST代表“用户不存在”这个业务异常。

  1. 在BizException类中添加USER_NOT_EXIST异常。代码如下:
public class BizException extends RuntimeException {

    private Integer code;

    public BizException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
    }

    public Integer getCode() {
        return code;
    }

    // 新增代码如下
    public static void throwUserNotExistException() {
        throw new BizException(ResultCodeEnum.USER_NOT_EXIST);
    }

}

在上述代码中,我们添加了一个静态方法throwUserNotExistException(),用于抛出“用户不存在”这个业务异常。

  1. 在UserController中添加查询用户信息的接口。若用户ID不存在,我们将抛出USER_NOT_EXIST异常。代码如下:
@PostMapping("/getUserInfo")
@ResponseBody
public Result getUserInfo(@RequestParam("userId") Integer userId) {
    // 查询用户信息,如果不存在则抛出USER_NOT_EXIST异常
    if (user == null) {
        BizException.throwUserNotExistException();
    }
    // 业务逻辑处理...
    return Result.success();
}

从上述代码中,我们可以看到,当参数不合法时,会抛出“用户不存在”这个业务异常。

  1. 最后,在ExceptionHandler类中捕获这个业务异常。代码如下:
@ExceptionHandler(BizException.class)
@ResponseBody
public Result handleBizException(BizException ex) {
    return new Result(ex.getCode(), ex.getMessage());
}

从上述代码中,我们可以看到,当捕获到业务异常时,会将异常码和异常信息返回给前端。

例子2:

假设我们有一个购物车服务,其中有一个添加商品到购物车的接口。当商品库存不足时,我们希望返回一个业务异常。

  1. 首先,在result包下新建ResultCodeEnum类,用于枚举所有异常的类型和信息。代码如下:
public enum ResultCodeEnum {

    SUCCESS(200, "操作成功!"),
    PRODUCT_NOT_ENOUGH(2001, "商品库存不足!"),
    PARAM_ERROR(2002, "参数错误!"),
    AUTH_FAILED(2003, "认证失败!"),
    EXCEPTION(9999, "系统异常,请稍后再试!");

    private Integer code;
    private String message;

    ResultCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

在上述代码中,我们枚举了所有异常的类型和信息,其中PRODUCT_NOT_ENOUGH代表“商品库存不足”这个业务异常。

  1. 在BizException类中添加PRODUCT_NOT_ENOUGH异常。代码如下:
public class BizException extends RuntimeException {

    private Integer code;

    public BizException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
    }

    public Integer getCode() {
        return code;
    }

    // 新增代码如下
    public static void throwProductNotEnoughException() {
        throw new BizException(ResultCodeEnum.PRODUCT_NOT_ENOUGH);
    }
}

在上述代码中,我们添加了一个静态方法throwUserNotExistException(),用于抛出“商品库存不足”这个业务异常。

  1. 在CartController中添加添加商品到购物车的接口。若商品库存不足,我们将抛出PRODUCT_NOT_ENOUGH异常。代码如下:
@PostMapping("/addProduct")
@ResponseBody
public Result addProduct(@RequestParam("productId") Integer productId, @RequestParam("count") Integer count) {
    // 判断商品库存是否充足
    if (product.getCount() < count) {
        BizException.throwProductNotEnoughException();
    }
    // 业务逻辑处理...
    return Result.success();
}

从上述代码中,我们可以看到,当商品库存不足时,会抛出“商品库存不足”这个业务异常。

  1. 最后,在ExceptionHandler类中捕获这个业务异常。代码如下:
@ExceptionHandler(BizException.class)
@ResponseBody
public Result handleBizException(BizException ex) {
    return new Result(ex.getCode(), ex.getMessage());
}

从上述代码中,我们可以看到,当捕获到业务异常时,会将异常码和异常信息返回给前端。

总的来说,为了优雅地实现全局异常处理,我们应该按以下步骤操作:添加异常枚举类、添加自定义异常、添加全局异常处理器、根据业务需求抛出自定义异常、在ExceptionHandler类中捕获这些异常,并向前端返回正确的异常信息。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot优雅地实现全局异常处理的方法详解 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • java性能优化四种常见垃圾收集器汇总

    Java性能优化四种常见垃圾收集器汇总 概述 垃圾收集是Java语言中非常重要的一部分,垃圾收集器的选择直接影响到JVM的性能和GC的效率。本文将介绍Java中常见的四种垃圾收集器,包括串行收集器、并行收集器、CMS收集器和G1收集器。同时,将详细介绍不同垃圾收集器之间的区别及他们的使用场景。 串行收集器 串行收集器是最简单的收集器,是JVM默认的垃圾收集器…

    Java 2023年5月19日
    00
  • MyBatis的9种动态标签详解

    MyBatis的9种动态标签详解 在使用MyBatis进行数据库操作时,动态SQL是一个经常用到的特性。MyBatis提供了9种动态标签,分别是<if>、<choose>、<when>、<otherwise>、<trim>、<where>、<set>、<foreach&…

    Java 2023年5月19日
    00
  • java中日期格式化的大坑

    关于“java中日期格式化的大坑”,我会从以下几个方面进行讲解: Java中日期格式化的基本知识 Java中日期格式化的坑点 解决Java中日期格式化的坑点的方法 两个示例来说明日期格式化的坑点 Java中日期格式化的基本知识 在Java中,要进行日期格式化,需要用到SimpleDateFormat类。该类是线程不安全的类,一般情况下,建议使用ThreadL…

    Java 2023年5月20日
    00
  • JavaWeb项目FullCalendar日历插件使用的示例代码

    下面是详细讲解JavaWeb项目中使用FullCalendar日历插件的攻略: 简介 FullCalendar是一款基于jQuery的开源工具,可以用来构建全功能、交互式日历和调度表。它可以用于Web应用程序、企业级管理系统、个人日历、日程安排等场景。使用FullCalendar可以快速高效地构建一个功能丰富的日历。下面是如何在JavaWeb项目中使用Ful…

    Java 2023年5月23日
    00
  • Java搜索与图论之DFS和BFS算法详解

    Java搜索与图论之DFS和BFS算法详解 DFS算法基本原理 DFS(深度优先搜索)指的是从图的某个顶点出发,访问其所有能到达的顶点,并且尽可能深的搜索其中一支支路径的搜索算法。遍历过的点存放到形成的树中。树中每个结点的祖先结点都位于它的所有子树中,它的祖先结点包括它父亲结点和它父亲的祖先结点。DFS一般采用递归或者栈实现,其算法流程如下: 访问起始顶点 …

    Java 2023年5月19日
    00
  • Spring循环依赖之问题复现详解

    下面我将详细讲解“Spring循环依赖之问题复现详解”的完整攻略,包含两条示例。 Spring循环依赖问题复现详解 什么是Spring循环依赖问题 当两个或更多的bean需要相互依赖时,就会发生Spring的循环依赖问题。当两个bean之间存在依赖时,容器负责解决依赖关系。但是,当存在循环依赖时,容器不能解决这个问题。 如何复现Spring循环依赖问题 下面…

    Java 2023年5月19日
    00
  • Java虚拟机装载和初始化一个class类代码解析

    Java虚拟机(JVM)的主要任务之一是加载Java类并执行它们的代码。在JVM将class文件转换为可执行代码并在执行时,Java虚拟机会完成以下过程: 类加载 验证类 准备阶段 解析阶段 初始化阶段 以下是这些过程的完整详细解释: 类加载:在Java程序运行时,JVM首先会搜索类加载路径(classpath)来查找并加载字节码文件。类加载器将字节码文件读…

    Java 2023年5月26日
    00
  • Java8新特性之深入解析日期和时间_动力节点Java学院整理

    Java8新特性之深入解析日期和时间_动力节点Java学院整理 为什么需要新的日期和时间API Java早期的日期和时间API出现了很多问题,如: API不一致:Java提供了大量日期和时间API,但它们之间的API不一致,这使得编写日期和时间代码非常困难。 可变性:Java早期的日期和时间API中的大多数类都是可变的,这意味着我们可以随时更改日期和时间,这…

    Java 2023年6月1日
    00
合作推广
合作推广
分享本页
返回顶部