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

文章目录

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

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

@ResponseBody


/*** 测试声明式异常处理*/
@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

// 全局异常处理器
//@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)
    实际上做项目的时候:我们编写全局异常处理器,处理所有异常

最终的异常处理方式

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


/*** 业务异常* 大型系统出现以下异常:异常处理文档,固化* 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();}
}

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

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;}}

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

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

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

@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.rhkb.cn/news/433376.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mitsuba 渲染基础

Mitsuba 渲染基础 0. Abstract1. 安装 Mitsuba21.1 下载 Mitsuba2 源码1.2 选择后端 (variants)1.3 编译 2. [Mitsuba2PointCloudRenderer](https://github.com/tolgabirdal/Mitsuba2PointCloudRenderer)2.1 Mitsuba2 渲染 XML2.2 Scene 场景的 XML 文件格式2.2.1 chair.npy to…

设计模式之装饰模式(Decorator)

前言 这个模式带给我们有关组合跟继承非常多的思考 定义 “单一职责” 模式。动态&#xff08;组合&#xff09;的给一个对象增加一些额外的职责。就增加功能而言&#xff0c;Decorator模式比生成子类&#xff08;继承&#xff09;更为灵活&#xff08;消除重复代码 & 减少…

JavaWeb招聘信息管理系统

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 spring-mybatis.xml3.5 spring-mvc.xml3.5 login.jsp 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优…

利用Langchain开发框架研发智能体Agent的过程,以及相关应用场景

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下本文主要介绍了利用langchain开发智能体agent的过程。文章首先阐述了项目背景&#xff0c;随后通过给出样例代码&#xff0c;详细展示了执行过程。此外&#xff0c;本文还探讨了该智能体agent在实际应用场景中的运用…

Excel根据一个值匹配一行数据

根据一个值从一个表中匹配一行数据&#xff0c;例如从左边的表中找到指定姓名的所有行数据 使用VLOOKUP函数&#xff0c;参数&#xff1a; Lookup_value&#xff1a;需要搜索的值&#xff0c;单个值 Table_array&#xff1a;被搜索的区域&#xff0c;是个表 Col_index_num&…

【Python基础(一)】

学习分享 一、基本语法1、输出print语句2、常量的写法3、运算符 (/) 与(//)4、字符串5、列表5.1、列表查询元素是否存在5.2、列表查询元素是否存在5.3、身份运算符5.4、列表的增删改查 6、元组6.1、tuple() 7、字典8、函数8.1、值传递8.2、引用传递8.3、函数的传参 二、文件的操…

AWS Network Firewall -NAT网关配置只应许白名单域名出入站

1. 创建防火墙 选择防火墙的归属子网(选择公有子网) 2. 创建规则白名单域名放行 3. 绑定相关规则

Spring JDBC及声明式事务

目录 Spring JDBC基础概念 Spring声明式事务 事务传播方式 Spring JDBC基础概念 Spring JDBC 封装了原生的JDBC API&#xff0c;使得处理关系型数据库更加简单。Spring JDBC的核心是JdbcTemplate&#xff0c;里面封装了大量数据库CRUD的操作。使用Spring JDBC…

[uni-app]小兔鲜-02项目首页

轮播图 轮播图组件需要在首页和分类页使用, 封装成通用组件 准备轮播图组件 <script setup lang"ts"> import type { BannerItem } from /types/home import { ref } from vue // 父组件的数据 defineProps<{list: BannerItem[] }>()// 高亮下标 const…

影响6个时序Baselines模型的代码Bug

前言 我是从去年年底开始入门时间序列研究&#xff0c;但直到最近我读FITS这篇文章的代码时&#xff0c;才发现从去年12月25号就有人发现了数个时间序列Baseline的代码Bug。如果你已经知道这个Bug了&#xff0c;那可以忽略本文&#xff5e; 这个错误最初在Informer&#xff0…

安科瑞Acrel-1000DP分布式光伏监控系统在鄂尔多斯市鄂托克旗巴音乌苏六保煤矿5MW分布式光伏项目中的应用

安科瑞 华楠 摘 要&#xff1a;分布式光伏发电就是将太阳能光伏板分散布置在各个区域&#xff0c;通过小规模、模块化的方式实现电能的并网或独立使用&#xff0c;这种发电方式具有就近发电、就近并网、就近转换、就近使用的特点。近年来&#xff0c;技术进步和政策支持推动了光…

Python在AI中的应用--使用决策树进行文本分类

Python在AI中的应用--使用决策树进行文本分类 文本分类决策树什么是决策树 scikit算法 使用scikit的决策树进行文章分类一个文本分类的Python代码使用的scikit APIs说明装入数据集决策树算法类类构造器&#xff1a; 构造决策树分类器产生输出评估输出结果分类准确度分类文字评估…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-22

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-22 引言: 全球最热销的国产游戏-《黑神话: 悟空》不仅给世界各地玩家们带来愉悦&#xff0c;而且对计算机人工智能研究也带来新的思考。在本期的论文速读中&#xff0c;我们带来一篇关于视觉语言模型&#xff0…

漫步者头戴式耳机好用吗?漫步者、西圣、万魔顶级机型测评对比

现在市面上有很多头戴式耳机&#xff0c;它们都基本精进主动降噪功能&#xff0c;以让大家在生活中能更少受到噪音的干扰&#xff0c;所以对于有降噪需求的人来说&#xff0c;头戴式耳机就是很适合他们的一种耳机。作为一名数码测评博主&#xff0c;也有很多人问我漫步者头戴式…

C++的vector优化

1、C中的动态数组一般是特指vector类 2、vector需要优化的原因之一是当我们push_back元素到数组中时&#xff0c;如果原来分配给动态数组的内存不够用了&#xff0c;那么就会找一块更大的内存空间分配给数组&#xff0c;把旧的内容复制到新的内存中去&#xff0c;这就是导致程…

大数据处理从零开始————3.Hadoop伪分布式和分布式搭建

1.伪分布式搭建&#xff08;不会用&#xff0c;了解就好不需要搭建&#xff09; 这里接上一节。 1.1 伪分布式集群概述 伪分布式集群就是只有⼀个服务器节点的分布式集群。在这种模式中&#xff0c;我们也是只需要⼀台机器。 但与本地模式不同&#xff0c;伪分布式采⽤了分布式…

C++简单缓冲区类设计

目录 1.引言 2.静态缓冲区 3.动态缓冲区 4.数据引用类 5.自动数据引用类 6.几种缓冲区的类关系图 7.注意事项 8.完整代码 1.引言 在C中&#xff0c;设计静态和动态缓冲区类时&#xff0c;需要考虑的主要差异在于内存管理的方式。静态缓冲区类通常使用固定大小的内存区域…

红绿灯倒计时读秒数字识别系统源码分享

红绿灯倒计时读秒数字识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of …

Power Automate 设置流Owner不生效的bug

在查找某个功能没生效时&#xff0c;定位到是一个Power automate的流停了&#xff0c;查看原因是因为创建流的owner被disable了 但是当把流的owner更新为可用的用户时&#xff0c;流依旧没被触发&#xff0c;触发的条件很简单&#xff0c;某个表的记录创建时&#xff0c;因为是…

Java流程控制语句——条件控制语句详解(附有流程图)#Java条件控制语句有哪些?#if-else、switch

在 Java 编程中&#xff0c;条件控制语句用于控制程序的执行路径&#xff0c;决定根据某些条件来选择执行某段代码或跳过某段代码。它们是 Java 编程的重要组成部分&#xff0c;帮助开发者根据不同的输入、状态或数据流来编写更加灵活和动态的代码。在本文中&#xff0c;我们将…