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项目启动报错:命令行太长解决的两种解决方法
SpringBoot项目启动时可能会遇到命令行太长的错误,本文介绍两种解决方法修改.idea\workspace.xml文件和执行maven的clean命令或重启IDEA,这些操作可以有效解决启动问题,需要的朋友可以参考下2024-10-10
Springboot下RedisTemplate的两种序列化方式实例详解
这篇文章主要介绍了Springboot下RedisTemplate的两种序列化方式,通过定义一个配置类,自定义RedisTemplate的序列化方式,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2022-09-09
Springboot使用POI进行excel文件的导出与下载方式
这篇文章主要介绍了Springboot使用POI进行excel文件的导出与下载方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-08-08
idea创建springboot项目(版本只能选择17和21)的解决方法
idea2023创建spring boot项目时,java版本无法选择11,本文主要介绍了idea创建springboot项目(版本只能选择17和21),下面就来介绍一下解决方法,感兴趣的可以了解一下2024-01-01
Java中BufferedReader与BufferedWriter类的使用示例
BufferedReader与BufferedWriter分别继承于Reader和Writer类,分别为字符的读取和写入添加缓冲功能,这里我们就来看一下Java中BufferedReader与BufferedWriter类的使用示例:2016-06-06


最新评论