SpringMVC异常全局捕获与错误响应的处理方法
目录
- 一编程式异常处理
- 二声明式异常处理
- 三 实际场景(拓展)
- 1 业务枚举类BizExceptionEnum 将所有可能出现的code与msg枚举封装
- 2 业务异常类(BizException)在这个方法当中接收BizExceptionEnum封装的信息,使用构造方法接收。
- 3 全局异常处理器GlobalExceptionHandle:最终在controller层处理业务逻辑的时候controller调用的是全局异常处理器的方法。
一编程式异常处理
编程式异常处理是通过在代码中 显式编写异常捕获逻辑(如 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 epythonnum BizExceptionEnum { //ORDER订单模块 ORDER_NOT_EXIST(10001, "订单php不存在"), 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感知异常,js被全局异常处理器捕获,然后调用异常对象的构造方法,将异常码和异常原因传递给异常对象, //通过这个构造方法,可以将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; imporpythont 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异常全局捕获内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论