Spring MVC中异常处理

1.全局异常处理

1.1什么是全局异常处理器

全局异常处理器是SpringMVC框架中的一种异常处理机制,用于统一处理由控制器抛出的异常。

全局异常处理器可以帮助我们捕获和处理控制器中的异常,并且根据不同的异常类型进行不同的处理操作,从而保障应用的健壮性和稳定性。

当然,SpringMVC中有内置的异常处理对象,但是呈现的结果对于用户端不友好,所以实际项目我们一般会使用全局异常处理器处理异常。

如果仅仅在项目中写下以下代码,会导致异常处理呈现的结果用户端难以理解。

@RestController
@RequestMapping("/v1/tests/")
public class TestController {@GetMapping("test")public JsonResult test(Integer id) {if (id < 0) {throw new IllegalArgumentException("id不能小于0");}return new JsonResult(200,"成功访问");}
}

如果我们能做到像一些企业级的异常应对措施,比如bilibili

当输入网址https://www.bilibili.com/id=111
这个地址根本不存在,结果返回一个“找不到页面”的页面。

这种处理效果是 前端+后端共同开发的效果,采用后端捕获异常 + 前端自定义错误页面渲染 的组合处理方式

前后端分离(REST 风格)

  • 用全局异常处理器统一返回结构化 JSON

  • 由前端(如 Vue、React)判断 status 或 code,显示漂亮的提示页面

{ "code": 404, "msg": "资源不存在", "data": null }

然后前端根据 code == 404 显示“找不到页面”的提示比如哔哩哔哩的效果。

1.2 全局异常处理器的配置


Spring MVC中的全局异常处理器可以通过以下方式进行配置:

1. 创建 exception.GlobalExceptionHandler 类,并添加异常处理方法;
使用 @ControllerAdvice 注解 + ResponseBody注解 或者 @RestControllerAdvice 注解标注该类;


2. 在异常处理方法上添加 @ExceptionHandler 注解,用于指定控制器中需要处理的异常类型。

@ControllerAdvice 

@ControllerAdvice 本质上是一个带有 @Component 的注解,Spring 启动时会将它的类扫描进容器中。

它内部利用 AOP 和 HandlerExceptionResolver 原理,在 Controller 执行过程中如果抛出了异常,就会查找有没有全局的异常处理器处理它。

@ExceptionHandler

@Exception注解 指定:这个方法能处理哪种异常类型

它的参数是异常对象(如 IllegalArgumentException e),Spring 会自动注入

你可以根据异常信息生成 JSON 响应、记录日志等

我们来进行优化上面的代码,在TestController基础上加上GlobalHandlerException类

@RestController
@RequestMapping("/v1/tests/")
public class TestController {@GetMapping("test")public JsonResult test(Integer id) {if (id < 0) {throw new IllegalArgumentException("id不能小于0");}return new JsonResult(200,"成功访问");}
}@Slf4j
@RestControllerAdvice
public class GlobalHandlerException {@ExceptionHandlerpublic String doHandlerIllegalArgumentExceptionException(IllegalArgumentException ex){log.error("ex : " + ex);return ex.getMessage();}
}

此时虽然没有哔哩哔哩网址那么华丽,但是总归是可以让用户清晰的知道不能传递id < 0这个限制了。

1.3 使用流程


1)创建全局异常处理器类


工程目录下创建 exception.GlobalExceptionHandler
@ControllerAdvice 注解


定义全局异常处理器,处理Controller中抛出的异常。
@RestControllerAdvice 注解
复合注解,是 @ControllerAdvice 注解和 @ResponseBody 注解的组合;
用于捕获Controller中抛出的异常并对异常进行统一的处理,还可以对返回的数据进行处理。


2)创建异常处理方法


在异常处理方法上添加 @ExceptionHandler 注解
@ExceptionHandler 注解
用于捕获Controller处理请求时抛出的异常,并进行统一的处理。
示例

/**ex.getMessage()方法:用于捕获异常信息
*/
@ExceptionHandler
public JsonResult doHandleRuntimeException(RuntimeException ex){log.error("error is " + ex.getMessage());return new JsonResult(StatusCode.OPERATION_FAILED,ex.getMessage());
}


1.4 全局异常处理器示例


1)微博详情页异常抛出

public JsonResult selectById(int id){if(id < 0) {throw new IllegalArgumentException("id值无效");}... ...
}


2)全局异常处理


exception.GlobalExceptionHandler 类


package cn.tedu.weibo.exception;import cn.tedu.weibo.common.response.JsonResult;
import cn.tedu.weibo.common.response.StatusCode;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;/*** RestControllerAdvice 是复合注解,描述的类型为一个全局异常处理对象类型,* 等价于:@ControllerAdvice+@ResponseBody* 当某个Controller方法中出现了异常,系统底层就会查找有没有定义全局异常处理对象。* 这个全局异常处理对象中有没有定义对应的异常处理方法,假如有就调用此方法处理异常。*/@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/***  @ExceptionHandler 描述的方法为一个异常处理方法,在此注解内部可以定义具体的异常处理*  类型(例如RuntimeException),此注解描述的方法需要定义一个异常类型的形式参数,*  通过这个参数接收具体的异常对象(也可以接收其异常类型对应的子类类型的异常)。*/@ExceptionHandlerpublic JsonResult doHandleRuntimeException(RuntimeException ex){log.error("error is " + ex.getMessage());return new JsonResult(StatusCode.OPERATION_FAILED,ex.getMessage());}/*** 假如用全局异常处理对象处理Controller类中出现的异常,全局异常处理对象会优先查找与Controller* 中相匹配的异常处理方法,假如没有,会查找对应异常的父类异常处理方法。*/@ExceptionHandlerpublic JsonResult doHandleRuntimeException(IllegalArgumentException ex){log.error("IllegalArgumentException is " + ex.getMessage());return new JsonResult(StatusCode.OPERATION_FAILED,ex.getMessage());}
}


3)重启工程测试


http://localhost:8080/v1/weibo/selectById?id=-1

2 关于Throwable

在开发实践中,通常会添加一个处理 Throwable 的方法,它将可以处理所有类型的异常,则不会再出现500错误!

Throwable 是 Java 所有异常(Exception)和错误(Error)的顶层父类

GlobalExceptionHandler中添加处理 Throwable 的方法

@ExceptionHandler
public JsonResult handleThrowable(Throwable e) {return new JsonResult(8888, "程序运行过程中出现了Throwable");
}

这个方法千万不要随便加,不然后续出了异常就看不出来了,可以等到项目开发的差不多了,测试bug也都找全了,准备上线了再添加。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88370.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88370.shtml

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

相关文章

imx6ull-系统移植篇2—— U-Boot 命令使用(上)

目录 前言 U-Boot 命令 help 信息查询命令 bdinfo printenv version 环境变量操作命令 setenv 和 saveenv 修改环境变量 新建环境变量 删除环境变量 内存操作命令 md nm mm mw cp cmp 网络操作命令 ping 命令 dhcp 命令 nfs 命令 tftp 命令 EMMC 和 S…

vector之动态二维数组的底层

引言&#xff1a;在计算机编程领域&#xff0c;二维动态数组是一种能够在程序运行期间动态调整其大小的二维数组数据结构。它与静态二维数组的关键区别在于&#xff0c;静态二维数组在编译时就需要确定其大小&#xff0c;而二维动态数组的大小可以在程序运行过程中根据实际需求…

第十六天,7月10日,八股

1、mybatis的延迟加载需要时才加载关联对象&#xff0c;而不是查询主对象时&#xff0c;立刻加载所有关联对象&#xff0c;这样可以提高查询性能并减少不必要的数据库访问&#xff0c;例如&#xff1a;一个订单表包含着商品列表&#xff08;一对多&#xff09;&#xff0c;当查…

CSS中的Element语法

1.1 Element语法1.1.1 案例 1. 快速生成10个div,并且每个div里面是从1到10的内容2.生成一个div标签&#xff0c;类名为one,并且同时生成一个id为first的p标签1.1.2 快速生成CSS样式语法 CSS基本采取简写形式即可 比如w22 按住tab键 可以生成 width:200px比如lh26px 按住tab键 可…

Go从入门到精通(21) - 一个简单web项目-添加swagger文档

Go从入门到精通(20)-一个简单web项目-服务搭建 文章目录Go从入门到精通(20)-一个简单web项目-服务搭建前言前期准备为API 添加 Swagger 文档1.安装依赖2.添加 Swagger 注释main.goapp.goapi.gopublic_handler.goauth_handler.gocommon_constant.gocommon_dto.gotoken_utils.go3…

自动驾驶环境感知:天气数据采集与融合技术实战

天气与我们日常各类生活场景密不可分&#xff0c;在驾驶场景里当车主发动汽车准备驶向目的地时&#xff0c;窗外的阴晴或许只是直观感受&#xff0c;而真正影响驾驶安全与行程效率的&#xff0c;可能是几公里外的突发暴雨、桥面的结冰预警&#xff0c;或是前方路段的强侧风等级…

基于svga+uniapp的微信小程序动画组件开发指南

lottie动画指南 效果 概述 本项目使用 svgaplayer.weapp.js 库来实现 SVGA 动画播放功能&#xff0c;支持在微信小程序、H5 等多端环境下播放高质量的矢量动画。SVGA 是一种跨平台的开源动画格式&#xff0c;具有文件小、渲染性能高的特点。 技术栈 核心库: svgaplayer.wea…

数据结构与算法——计算直线的交点数

前言&#xff1a; 这是之前做的一道笔试题&#xff0c;当时没写出来烦恼很久&#xff0c;这次记录一下。 题目链接&#xff1a; Dotcpp--题目 1174: 计算直线的交点数 参考文章&#xff1a; CSDN--槐阳7--计算直线的交点数 题目&#xff1a; 解题思考&#xff1a; 在当时…

大模型及agent开发6 OpenAI Assistant API 高阶应用 - 流式输出功能

1.Assistant API 的主要优点&#xff1a; 减少编码工作量、自动管理上下文窗口、安全的访问控制、工具和文档的轻松集成 本节讲应用设计和性能流式输出&#xff1a;借助流式输出&#xff0c;可以让应用程序实时处理和响应用户输入。具体来说&#xff0c;这种技术允许数据在生成…

React Native安卓刘海屏适配终极方案:仅需修改 AndroidManifest.xml!

&#x1f4cc; 问题背景在 React Native 开发中&#xff0c;我们经常会遇到安卓设备刘海屏&#xff08;Notch&#xff09;适配问题。即使正确使用了 react-native-safe-area-context 和 react-navigation&#xff0c;在一些安卓设备&#xff08;如小米、华为、OPPO 等&#xff…

Spring Boot整合MyBatis+MySQL实战指南(Java 1.8 + 单元测试)

一、环境准备 开发工具&#xff1a;IntelliJ IDEA 2023.1 JDK 1.8.0_382 Maven3.6.3数据库&#xff1a;MySQL 8.0.21依赖版本&#xff1a;<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifact…

游戏开发日记

如何用数据表来储存&#xff0c;位置坐标&#xff08;XYZ&#xff09;&#xff1a;决定了对象在世界中的摆放资源ID / 图片URL&#xff1a;决定了使用什么模型或贴图事件ID / 特效&#xff1a;是否触发某些事件&#xff08;例如点击、交互&#xff09;逻辑索引&#xff08;Grid…

如何使用xmind编写测试用例

如何使用xmind编写测试用例为什么要使用xmind&#xff1f;使用xmind编写测试用例是为了梳理我们的思路。使用xmind编写测试用例的思路是什么&#xff1f;先进行分析再提取测试用例。 例如下面的注册功能的测试用例的分析&#xff1a; 分析&#xff1a; 先提取出需要测试的功能点…

使用LLaMA-Factory微调Qwen2.5-VL-3B 的目标检测任务-数据集格式转换(voc 转 ShareGPT)

一、LLaMA-Factory Qwen2.5-VL ShareGPT 格式要求ShareGPT 格式就是多轮对话的 list&#xff0c;每条数据如下&#xff1a;[{"conversations": [{"from": "user", "value": "<image>\n请标注图片中的所有目标及其类别和位…

【SkyWalking】服务端部署与微服务无侵入接入实战指南

【SkyWalking】服务端部署与微服务无侵入接入实战指南 &#x1f4a1; SkyWalking 系列总引导 在微服务架构快速演进的今天&#xff0c;如何有效实现服务链路追踪、性能分析、日志采集与自动化告警&#xff0c;成为系统稳定性的关键保障手段。 SkyWalking&#xff0c;作为 Apa…

LVDS系列20:Xilinx 7系ISERDESE2原语(一)

Xilinx 7系FPGA bank的io单元如下&#xff1a;Hr bank比hp bank少odelaye2组件&#xff0c;两者的idelaye2组件后面&#xff0c;都有iserdese2组件&#xff1b; iserdese2组件是一种专用的串并转换器或称解串器&#xff0c;用于高速源同步应用&#xff0c;如大部分LVDS信号解析…

【U-Boot】Shell指令

目录 U-Boot 三个Shell U-Boot Shell Linux Shell shell脚本 总结 U-Boot Shell命令 帮助命令 部分命令分类与功能说明 一、基础操作与信息查询 二、内存操作 三、启动管理 四、文件系统操作 五、设备与分区管理 六、环境变量 七、诊断与调试 八、特殊功能 九…

《Revisiting Generative Replay for Class Incremental Object Detection》阅读笔记

摘要Abstract部分 原文 Generative replay has gained significant attention in class-incremental learning; however, its application to Class Incremental Object Detection (CIOD) remains limited due to the challenges in generating complex images with precise …

Mysql: Bin log原理以及三种格式

目录 一、什么是 Binlog&#xff1f; 二、Binlog 的应用场景与案例 1. 数据恢复 (Point-in-Time Recovery) 2. 主从复制 (Master-Slave Replication) 3. 数据审计 三、Binlog 的三种格式 1. STATEMENT 模式 (Statement-Based Logging - SBL) 2. ROW 模式 (Row-Based Log…

LiteHub之文件下载与视频播放

文件下载 前端请求 箭头函数 //这个箭头函数可以形象理解为&#xff0c;x流入&#xff08;>&#xff09;x*x, //自然而然>前面的就是传入参数,>表示函数体 x > x * x//相当于 function (x) {return x * x; }//如果参数不是一个&#xff0c;就需要用括号()括起来…