SpringMVC异常全局捕获与错误响应的处理方法

 更新时间:2025年03月18日 09:35:41   作者:小安同学iter  
编程式异常处理是通过在代码中 显式编写异常捕获逻辑(如 try-catch 块)来管理异常的方式,开发者需要手动处理每一个可能抛出异常的代码段,本文给大家介绍SpringMVC异常全局捕获与错误响应的处理方法,感兴趣的朋友一起看看吧

一编程式异常处理

编程式异常处理是通过在代码中 显式编写异常捕获逻辑(如 try-catch 块)来管理异常的方式。开发者需要手动处理每一个可能抛出异常的代码段。

代码实现:

package org.example.springmvc.controller;
import org.example.springmvc.common.R;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class helloController {
    @GetMapping(value = "/hello")
    public R hello() {
        // 编程式的异常处理
        try {
            int i = 1 / 0;
            return R.ok(i);
        } catch (Exception e) {
            return R.error(100, "执行异常");
        }
    }
}

运行结果:

二声明式异常处理

声明式异常处理是通过 配置或注解 将异常处理逻辑与业务代码解耦,通常由框架统一管理。例如,在 Spring 中通过 @ControllerAdvice 和 @ExceptionHandler 实现全局异常处理。

代码实现:

package org.example.springmvc.controller;
import org.example.springmvc.common.R;
import org.springframework.web.bind.annotation.*;
@RestController
public class HelloController {
    @GetMapping(value = "/hello")
    public R hello(@RequestParam(value = "i", defaultValue = "0") Integer i) {
        int j = 1 / i;
        return R.ok(j);
    }
    /**
     * 如果Controller本类出现异常,会自动在本类中寻找有没有@ExceptionHandler注解的方法,如果有,则执行
     * 可以根据需求添加多个@ExceptionHandler注解的方法
     * .@ExceptionHandler注解接收多个参数,表示可以拦截多个异常类型
     *
     */
    @ExceptionHandler(ArithmeticException.class)
    public R handleArithmeticException(ArithmeticException e) {
        return R.error(100, "是执行异常" + e.getMessage());
    }
    @ExceptionHandler(Exception.class)
    public R handleException(Exception e) {
        return R.error(200, "异常" + e.getMessage());
    }
}

改进:

单一的@ExceptionHandler注解只会处理当前类 @ExceptionHandler+@ControllerAdvice注解可以完成全局统一处理

处理优先级:本类大于外类,精确大于全局

SpringBoot底层对SpringMVC有兜底处理机制(没有写这个异常处理逻辑)

package org.example.springmvc.advice;
import org.example.springmvc.common.R;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//@ResponseBody
//@ControllerAdvice
@RestControllerAdvice//合成注解
public class GlobalExceptionHandler {
    @ExceptionHandler(ArithmeticException.class)
    public R handleArithmeticException(ArithmeticException e) {
        return R.error(100, "是执行异常" + e.getMessage());
    }
    @ExceptionHandler(Exception.class)
    public R handleException(Exception e) {
        return R.error(200, "异常" + e.getMessage());
    }
}

运行结果:

三 实际场景(拓展)

问题场景:

Controller层业务逻辑感知异常,被全局异常处理器捕获,然后调用异常对象的构造方法,使用业务枚举类将异常码和异常原因传递给异常对象,最终被全局处理器解决

业务抛出:

throw new BizException(BizExceptionEnum.ORDER_NOT_EXIST);

1 业务枚举类BizExceptionEnum 将所有可能出现的code与msg枚举封装

package org.example.springmvc.exception;
public enum BizExceptionEnum {
    //ORDER订单模块
    ORDER_NOT_EXIST(10001, "订单不存在"),
    ORDER_STATUS_ERROR(10002, "订单状态错误"),
    ORDER_PAID(10003, "订单已支付"),
    ORDER_CANCEL_FAIL(10004, "订单取消失败"),
    ORDER_PAY_FAIL(10005, "订单支付失败"),
    //PRODUCT商品模块
    PRODUCT_STOCK_NOT_ENOUGH(20001, "商品库存不足"),
    PRODUCT_OFF_SALE_OR_DELETE(20002, "商品下架或删除"),
    PRODUCT_NOT_EXIST(20003, "商品不存在"),
    PRODUCT_STOCK_ERROR(20004, "商品库存有误"),
    //USER用户模块
    USER_NOT_EXIST(30001, "用户不存在"),
    USER_PASSWORD_ERROR(30002, "密码错误"),
    USER_ACCOUNT_ERROR(30003, "账号错误"),
    USER_ACCOUNT_LOCK(30004, "账号已被锁定"),
    USER_LOGIN_FAIL(30005, "用户名或密码错误"),
    USER_ACCOUNT_FORBIDDEN(30006, "账号已被禁用"),
    //OTHER其他模块
    OTHER_ERROR(40001, "其他错误"),
    ;
    private final int code;
    private final String msg;
    BizExceptionEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}

2 业务异常类(BizException)在这个方法当中接收BizExceptionEnum封装的信息,使用构造方法接收。

package org.example.springmvc.exception;
public class BizException extends RuntimeException{
    //业务异常码,业务异常原因
    private final Integer code;
    private final String msg;
    public BizException(Integer code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
    }
    //Controller感知异常,被全局异常处理器捕获,然后调用异常对象的构造方法,将异常码和异常原因传递给异常对象,
    //通过这个构造方法,可以将BizExceptionEnum枚举对象 传给 BizException,然后抛出异常
    public BizException(BizExceptionEnum bizExceptionEnum) {
        super(bizExceptionEnum.getMsg());
        this.code = bizExceptionEnum.getCode();
        this.msg = bizExceptionEnum.getMsg();
    }
    public Integer getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}

3 全局异常处理器GlobalExceptionHandle:最终在controller层处理业务逻辑的时候controller调用的是全局异常处理器的方法。

package org.example.springmvc.advice;
import org.example.springmvc.common.R;
import org.example.springmvc.exception.BizException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//@ResponseBody
//@ControllerAdvice
@RestControllerAdvice//合成注解
public class GlobalExceptionHandler {
    @ExceptionHandler(ArithmeticException.class)
    public R handleArithmeticException(ArithmeticException e) {
        return R.error(100, "是执行异常" + e.getMessage());
    }
    @ExceptionHandler(BizException.class)//这里传递的e已经提前封装好了
    public R HandleBizException(BizException e) {
        return R.error(e.getCode(), e.getMsg());
    }
    @ExceptionHandler(Throwable.class)
    public R handleThrowable(Throwable e) {
        return R.error(500, "异常" + e.getMessage());
    }
}

到此这篇关于SpringMVC异常全局捕获与错误响应的处理方法的文章就介绍到这了,更多相关SpringMVC异常全局捕获内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于SpringBoot+JPackage构建独立安装包的操作流程

    基于SpringBoot+JPackage构建独立安装包的操作流程

    从JDK 14开始,Java官方引入了JPackage工具(在JDK 16 正式成为标准功能),它能够将 Java 应用打包成特定平台的原生安装包,本文将介绍如何使用 JPackage 工具将 Spring Boot 项目打包成 Windows、macOS 或 Linux 平台的原生安装包,需要的朋友可以参考下
    2026-01-01
  • Spring cloud 查询返回广告创意实例代码

    Spring cloud 查询返回广告创意实例代码

    在本篇文章里小编给大家整理的是关于Spring cloud 查询返回广告创意实例代码,需要的朋友们可以跟着学习下。
    2019-08-08
  • springboot中swagger快速启动流程

    springboot中swagger快速启动流程

    这篇文章主要介绍了springboot中的swagger快速启动流程,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • SpringBoot项目中同时操作多个数据库的实现方法

    SpringBoot项目中同时操作多个数据库的实现方法

    在实际项目开发中可能存在需要同时操作两个数据库的场景,本文主要介绍了SpringBoot项目中同时操作多个数据库的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • java中的AWT事件处理问题

    java中的AWT事件处理问题

    这篇文章主要介绍了java中的AWT事件处理问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • MyBatis实战之动态生成SQL详解

    MyBatis实战之动态生成SQL详解

    这篇文章主要为大家详细介绍了如何使用MyBatis实现动态生成SQL,可以告别硬编码,拥抱智能SQL生成,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-07-07
  • 使用webservice自定义注解处理参数加解密问题

    使用webservice自定义注解处理参数加解密问题

    这篇文章主要介绍了使用webservice自定义注解处理参数加解密问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • idea鼠标控制放大缩小的操作

    idea鼠标控制放大缩小的操作

    这篇文章主要介绍了idea鼠标控制放大缩小的操作教程,具有很好的参考价值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • 基于Java+SSM实现电影院购票系统

    基于Java+SSM实现电影院购票系统

    今天小编给大家带来一款SSM的电影院售票系统,非常不错的一个项目,是学习​javaweb编程必备。文中的示例代码讲解详细,需要的可以参考一下
    2022-04-04
  • JavaSe和JavaEE的区别原理面试题精讲

    JavaSe和JavaEE的区别原理面试题精讲

    这篇文章主要为大家介绍了JavaSe和JavaEE的区别原理面试题精讲,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09

最新评论