Spring异常处理-@ExceptionHandler-@ControllerAdvice-全局异常处理

server/2024/10/25 18:33:28/

文章目录

  • @ResponseBody
  • @ControllerAdvice
  • 最终的异常处理方式

异常的处理分两类
编程式处理:也就是我们的try-catch
声明式处理:使用注解处理
在这里插入图片描述

@ResponseBody

java">
/*** 测试声明式异常处理*/
@RestController
public class HelloController {//编程式的异常处理;//如果大量业务都需要加异常处理代码的话,会很麻烦
//        try {
//            //执行业务
//
//        }catch (Exception e){
//            return R.error(100,"执行异常");
//        }@GetMapping("/hello")public R hello(@RequestParam(value = "i",defaultValue = "0") Integer i) throws FileNotFoundException {int j = 10 / i;//        FileInputStream inputStream = new FileInputStream("D:\\123.txt");String s = null;s.length();return R.ok(j);}/*** 1、如果Controller本类出现异常,会自动在本类中找有没有@ExceptionHandler标注的方法,*    如果有,执行这个方法,它的返回值,就是客户端收到的结果*  如果发生异常,多个都能处理,就精确优先* @return*/@ResponseBody@ExceptionHandler(ArithmeticException.class)public R handleArithmeticException(ArithmeticException ex){System.out.println("【本类】 - ArithmeticException 异常处理");return R.error(100,"执行异常:" + ex.getMessage());}@ExceptionHandler(FileNotFoundException.class)public R handleException(FileNotFoundException ex){System.out.println("【本类】 - FileNotFoundException 异常处理");return R.error(300,"文件未找到异常:" + ex.getMessage());}@ExceptionHandler(Throwable.class)public R handleException02(Throwable ex){System.out.println("【本类】 - Throwable 异常处理");return R.error(500,"其他异常:" + ex.getMessage());}}

@ExceptionHandler只能处理本类的
所以其他类的报错怎么办呢?
使用@ControllerAdvice

@ControllerAdvice

java">// 全局异常处理器
//@ResponseBody   // 结果还是以JSON的形式写出去
//@ControllerAdvice //告诉SpringMVC,这个组件是专门负责进行全局异常处理的
@RestControllerAdvice   // 合成注解
public class GlobalExceptionHandler {/*** 如果出现了异常:本类和全局都不能处理,* SpringBoot底层对SpringMVC有兜底处理机制;自适应处理(浏览器响应页面、移动端会响应json)* 最佳实践:我们编写全局异常处理器,处理所有异常* <p>* 前端关心异常状态,后端正确业务流程。* 推荐:后端只编写正确的业务逻辑,如果出现业务问题,后端通过抛异常的方式提前中断业务逻辑。前端感知异常;* <p>* 异常处理:* 1、** @param e* @return*/@ExceptionHandler(ArithmeticException.class)public R error(ArithmeticException e) {System.out.println("【全局】 - ArithmeticException 处理");return R.error(500, e.getMessage());}@ExceptionHandler(BizException.class)public R handleBizException(BizException e) {Integer code = e.getCode();String msg = e.getMsg();return R.error(code, msg);}@ExceptionHandler(value = MethodArgumentNotValidException.class)public R methodArgumentNotValidException(MethodArgumentNotValidException ex) {//1、result 中封装了所有错误信息BindingResult result = ex.getBindingResult();List<FieldError> errors = result.getFieldErrors();Map<String, String> map = new HashMap<>();for (FieldError error : errors) {String field = error.getField();String message = error.getDefaultMessage();map.put(field, message);}return R.error(500, "参数错误", map);}// 最终的兜底@ExceptionHandler(Throwable.class)public R error(Throwable e) {System.out.println("【全局】 - Exception处理" + e.getClass());return R.error(500, e.getMessage());}}

异常处理优先级

  • 本类 > 全局
  • 精确 > 模糊
    如果出现了异常,本类和全局都不能处理,SpringMVC会兜底处理机制: 自适应处理(什么样的客户端返回什么,要是浏览器就返回一个错误页面,要是客户端,比如Postman,返回json)
    实际上做项目的时候:我们编写全局异常处理器,处理所有异常

最终的异常处理方式

前端关心异常状态
后端正确业务流程
推荐:后端只编写正确的业务逻辑,如果出现业务问题,后端通过抛异常的方式提前中断业务逻辑。前端感知异常;
定义一个业务异常

java">
/*** 业务异常* 大型系统出现以下异常:异常处理文档,固化* 1、订单  1xxxx*      10001 订单已关闭*      10002 订单不存在*      10003 订单超时*      .....* 2、商品  2xxxx*       20001 商品已下架*       20002 商品已售完*       20003 商品库存不足*       ......* 3、用户*      30001 用户已注册*      30002 用户已登录*      30003 用户已注销*      30004 用户已过期** 4、支付*      40001 支付失败*      40002 余额不足*      40003 支付渠道异常*      40004 支付超时** 5、物流*      50001 物流状态错误*      50002 新疆得加钱*      50003 物流异常*      50004 物流超时** 异常处理的最终方式:* 1、必须有业务异常类:BizException* 2、必须有异常枚举类:BizExceptionEnume  列举项目中每个模块将会出现的所有异常情况* 3、编写业务代码的时候,只需要编写正确逻辑,如果出现预期的问题,需要以抛异常的方式中断逻辑并通知上层。* 4、全局异常处理器:GlobalExceptionHandler;  处理所有异常,返回给前端约定的json数据与错误码*/@Data
public class BizException extends RuntimeException {private Integer code; //业务异常码private String msg; //业务异常信息public BizException(Integer code, String message) {super(message);this.code = code;this.msg = message;}public BizException(BizExceptionEnume exceptionEnume) {super(exceptionEnume.getMsg());this.code = exceptionEnume.getCode();this.msg = exceptionEnume.getMsg();}
}

为了便于管理,我们把所有的异常码和异常信息写一个枚举类。

java">public enum BizExceptionEnume {// ORDER_xxx:订单模块相关异常// PRODUCT_xxx:商品模块相关异常// 动态扩充.....ORDER_CLOSED(10001, "订单已关闭"),ORDER_NOT_EXIST(10002, "订单不存在"),ORDER_TIMEOUT(10003, "订单超时"),PRODUCT_STOCK_NOT_ENOUGH(20003, "库存不足"),PRODUCT_HAS_SOLD(20002, "商品已售完"),PRODUCT_HAS_CLOSED(20001, "商品已下架");@Getterprivate Integer code;@Getterprivate String msg;private BizExceptionEnume(Integer code, String msg) {this.code = code;this.msg = msg;}}

然后在我们的全局异常处理器中处理我们的业务异常

java"> @ExceptionHandler(BizException.class)public R handleBizException(BizException e) {Integer code = e.getCode();String msg = e.getMsg();return R.error(code, msg);}

在业务中就可以这样用了。

java">@Overridepublic void updateEmp(Employee employee) {//防null处理。考虑到service是被controller调用的;//controller层传过来的employee 的某些属性可能为null,所以先处理一下//怎么处理?Long id = employee.getId();if(id == null){ //页面没有带id//中断的业务的时候,必须让上层及以上的链路知道中断原因。推荐抛出业务异常throw new BizException(BizExceptionEnume.ORDER_CLOSED);}……

http://www.ppmy.cn/server/122301.html

相关文章

超详细的XML介绍【附带dom4j操作XML】

XML简介 XML&#xff08;EXtensible Markup Language&#xff09;,可扩展标记语言** 特点 XML与操作系统、编程语言的开发平台无关 实现不同系统之间的数据交换 作用 数据交互 配置应用程序和网站 Ajax基石 XML文档结构&#xff1a; 1.声明 一般是XML文档的第一行 2…

强推!超真实的小红书AI绘图Flux大模型,一键生成超逼真的假期打卡照,AI日常照片|极致逼真模型

大家好&#xff0c;我是画画的小强 今天给大家介绍一款Flux LORA模型&#xff1a;Flux_小红书真实风格丨日常照片丨极致逼真&#xff0c;这是一款以小红书真实感风格为主题的Flux LORA模型。该模型极度真实&#xff0c;自然日常&#xff0c;直出图集猜测训练数据可能来源于真实…

Flink架构

Apache Flink — Stateful Computations over Data Streams 1 状态化流处理 第一章首先比较了传统数据处理架构的两个主要内容&#xff1a;事务型处理和分析型处理&#xff0c;其中事务型处理是说企业在日常运作过程中产生的各类应用的数据存储层。数据应用在每处理一条事件&…

AWS账单不支付账号会停用吗?

大家好&#xff0c;今天九河云来和大家聊聊一个大家都很关心的问题——如果AWS账单不支付&#xff0c;账号会停用吗&#xff1f; 首先&#xff0c;AWS&#xff08;Amazon Web Services&#xff09;是亚马逊旗下的一项云服务&#xff0c;它提供了各种各样的云计算资源&#xff…

Springboot Mybatis 动态SQL

动态SQL <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace"com.wzb.SqlImprove2024…

Tomcat may not be running

一、问题背景 tomcat7运行在JDK1.7上&#xff0c;可启动tomcat&#xff0c;但是停止时报错误&#xff0c;如下&#xff1a; 二、适用条件 JDK1.7/JDK1.8 tomcat7 三、解决方法 1、查找java路径 which java 2、修改文件 找到/usr/lib/jvm/jdk1.7.0_80/jre/lib/security/j…

css 自定义滚动条样式

* { scrollbar-color: auto !important; scrollbar-width: auto; } //滚动条宽高 ::-webkit-scrollbar { width: 4px; height: 4px; background: transparent; } ::-webkit-scrollbar-thumb { //滑块部分 border-radius: 5px; background-color: rgba(32, 224, 254, 1); } ::-…

开源推理库介绍:ZML,Distributed Llama,EXO | LeetTalk Daily

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心筛选&#xff0c;为您带来最新鲜、最具洞察力的科技新闻。 开源推理库的出现为机器学习模型的部署、监控和扩展提供了强大的支持。我们介绍三个重要的开源推理库&#xff1a;ZML、Distributed Llama …