解密Spring MVC异常处理:从局部到全局,打造稳固系统的关键步骤

😀前言
在现代软件开发中,异常处理是不可或缺的一部分,它能够有效地提高系统的稳定性和健壮性。在Spring MVC框架中,异常处理机制起着至关重要的作用,它允许开发者在程序运行过程中捕获、处理和报告异常,从而保障用户体验和系统可靠性。本文将带您深入探索Spring MVC异常处理的核心概念、不同的处理策略以及如何构建一个稳固的异常处理机制。

🏠个人主页:尘觉主页
在这里插入图片描述

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉

在csdn获奖荣誉: 🏆csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 💓Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🤗 端午大礼包获得者

💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊

文章目录

  • 🥰解密Spring MVC异常处理:从局部到全局,打造稳固系统的关键步骤
    • 异常处理-基本介绍
    • 😀局部异常
      • 演示局部异常处理机制
      • 创建MyExceptionHandler
      • 创建exception.jsp
      • 创建exception_mes.jsp
      • 测试(页面方式)
      • 测试(Postman 方式)
    • 😀全局异常
      • 解读
      • 修改MyExceptionHandler增加方法
      • 修改exception.jsp增加语句
      • 测试
    • 😉异常优先级
      • 异常处理时:局部异常 优先级高于 全局异常
      • 需求
      • 创建AgeException.java
      • 修改MyExceptionHandler增加方法
      • 修改 exception.jsp, 增加超链
      • 完成测试(页面测是)
      • 完成测试(postman)
    • 😊SimpleMappingExceptionResolver
    • 基本说明
    • 代码演示
      • 修改 MyExceptionHandler.java , 增加方法test03
      • 配置 springDispatcherServlet-servlet.xml
      • 创建arrEx.jsp
      • 修改 exception.jsp
      • 并完成测试
    • 🤗对未知异常进行统一处理
      • 修改 MyExceptionHandler.java , 增加方法test04
      • 创建allEx.jsp
      • 修改 exception.jsp , 增加超链接
      • 并完成测试
    • 异常处理的优先级梳理
      • ● 异常处理的优先级
    • 😘全部xml配置
    • 😄总结

🥰解密Spring MVC异常处理:从局部到全局,打造稳固系统的关键步骤

异常处理-基本介绍

  1. Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler 映射、数据
    绑定以及目标方法执行时发生的异常

  2. 主要处理 Handler 中用 -@ExceptionHandler 注解定义的方法。

  3. ExceptionHandlerMethodResolver 内部若找不到–@ExceptionHandler 注解的话,会找
    @ControllerAdvice 类的@ExceptionHandler 注解方法,这样就相当于一个全局异常处理器

😀局部异常

演示局部异常处理机制

如果不处理异常, 非常的不友好

img

创建MyExceptionHandler

    @ExceptionHandler({ArithmeticException.class,NullPointerException.class})public String localException(Exception ex, HttpServletRequest request){System.out.println("局部异常信息是-" + ex.getMessage());//如何将异常的信息带到下一个页面.request.setAttribute("reason", ex.getMessage());return "exception_mes";}/*** 解读* 1. 编写方法,模拟异常, 算术异常* 2. 如果我们不做异常处理,是由tomcat默认页面显示**/@RequestMapping(value = "/testException01")public String test01(Integer num) {int i = 9 / num;return "success";}

创建exception.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>异常信息</title>
</head>
<body>
<h1>测试异常</h1>
<a href="<%=request.getContextPath()%>/testException01?num=0">点击测试局部异常</a><br><br>
</body>
</html>

创建exception_mes.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>异常信息提示</title>
</head>
<body>
<h1>朋友, 程序发生了异常...</h1>
异常信息- ${requestScope.reason}
</body>
</html>

测试(页面方式)

浏览器 http://localhost:8080/springmvc/exception.jsp

img

img

测试(Postman 方式)

img

😀全局异常

ExceptionHandlerMethodResolver 内部若找不到@ExceptionHandler 注解的话,会找
@ControllerAdvice 类的@ExceptionHandler 注解方法, 这样就相当于一个全局异常处理器

这个上面已经演示了这里只是补充说明

解读

  1. 这里我们模拟了一个异常 NumberFormatException
  2. 该异常没有在局部异常处理,按照异常处理机制,就会交给全局异常处理类处理

修改MyExceptionHandler增加方法

    @RequestMapping(value = "/testGlobalException")public String global(){//解读//1. 这里我们模拟了一个异常 NumberFormatException//2. 该异常没有在局部异常处理,按照异常处理机制,就会交给全局异常处理类处理int num = Integer.parseInt("hello");return "success";}

修改exception.jsp增加语句

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>异常信息</title>
</head>
<body>
<h1>测试异常</h1>
<a href="<%=request.getContextPath()%>/testException01?num=0">点击测试局部异常</a><br><br>
<a href="<%=request.getContextPath()%>/testGlobalException">点击测试全局异常</a><br><br></body>
</html>

测试

如上面测试一样

😉异常优先级

异常处理时:局部异常 优先级高于 全局异常

需求

通过@ResponseStatus 注解, 可以自定义异常的说明

创建AgeException.java

@ResponseStatus(reason = "年龄需要在1-120之间", value = HttpStatus.BAD_REQUEST)
public class AgeException extends RuntimeException {public AgeException() {}public AgeException(String message) {super(message);}
}

修改MyExceptionHandler增加方法

    @RequestMapping(value = "/testException02")public String test02(){throw new AgeException("年龄必须在1-120之间~~~");}

修改 exception.jsp, 增加超链

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>异常信息</title>
</head>
<body>
<h1>测试异常</h1>
<a href="<%=request.getContextPath()%>/testException01?num=0">点击测试局部异常</a><br><br>
<a href="<%=request.getContextPath()%>/testGlobalException">点击测试全局异常</a><br><br>
<a href="<%=request.getContextPath()%>/testException02">点击测试自定义异常</a><br/><br/>
</body>
</html>

完成测试(页面测是)

浏览器 http://localhost:8080/springmvc/exception.jsp

img

完成测试(postman)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

😊SimpleMappingExceptionResolver

基本说明

  1. 如果希望对所有异常进行统一处理,可以使用 SimpleMappingExceptionResolver
  2. 它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常
  3. 需要在 ioc容器中配置

代码演示

对数组越界异常进行统一处理,使用 SimpleMappingExceptionResolver处理

修改 MyExceptionHandler.java , 增加方法test03

 @RequestMapping(value = "/testException03")public String test03(){int[] arr = new int[]{3,9,10,190};//抛出一个数组越界的异常 ArrayIndexOutOfBoundsExceptionSystem.out.println(arr[90]);return "success";}

配置 springDispatcherServlet-servlet.xml

解释一下为什么只写arrEX因为我们前面配置了 prefix/WEB-INF/pages/和suffix .jsp所以默认会拼接

    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop></props></property></bean>

创建arrEx.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>数组越界异常</title>
</head>
<body>
<h1><异常></异常>信息: 数组越界异常</h1>
</body>
</html>

修改 exception.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>异常信息</title>
</head>
<body>
<h1>测试异常</h1>
<a href="<%=request.getContextPath()%>/testException01?num=0">点击测试局部异常</a><br><br>
<a href="<%=request.getContextPath()%>/testGlobalException">点击测试全局异常</a><br><br>
<a href="<%=request.getContextPath()%>/testException02">点击测试自定义异常</a><br/><br/>
<a href="<%=request.getContextPath()%>/testException03">点击测试统一处理异常</a><br/><br/>
</body>
</html>

并完成测试

(页面测试), 浏览器 http://localhost:8080/springmvc/exception.jsp

(postman) 测 http://localhost:8080/springmvc/testException03

页面就不展示了

🤗对未知异常进行统一处理

对未知异常进行统一处理,使用 SimpleMappingExceptionResolver

    <!--配置统一处理异常Bean--><bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop><prop key="java.lang.Exception">allEx</prop></props></property></bean>

修改 MyExceptionHandler.java , 增加方法test04

    //如果发生了没有归类的异常, 可以给出统一提示页面@RequestMapping(value = "/testException04")public String test04(){String str = "hello";//这里会抛出 StringIndexOutOfBoundsExceptionchar c = str.charAt(10);return "success";}

创建allEx.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>未知异常信息</title>
</head>
<body>
<h1>朋友,系统发生了未知异常~, 请联系网站管理员</h1>
</body>
</html>

修改 exception.jsp , 增加超链接

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>异常信息</title>
</head>
<body>
<h1>测试异常</h1>
<a href="<%=request.getContextPath()%>/testException01?num=0">点击测试局部异常</a><br><br>
<a href="<%=request.getContextPath()%>/testGlobalException">点击测试全局异常</a><br><br>
<a href="<%=request.getContextPath()%>/testException02">点击测试自定义异常</a><br/><br/>
<a href="<%=request.getContextPath()%>/testException03">点击测试统一处理异常</a><br/><br/>
<a href="<%=request.getContextPath()%>/testException04">点击测试未知异常</a><br/><br/>
</body>
</html>

并完成测试

(页面测试), 浏览器 http://localhost:8080/springmvc/exception.jsp

(postman) 测试http://localhost:8080/springmvc/testException04

异常处理的优先级梳理

● 异常处理的优先级

局部异常 > 全局异常 > SimpleMappingExceptionResolver > tomcat 默认机制

😘全部xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--配置自动扫描包--><context:component-scan base-package="com.wyxdu.web"/><!--配置视图解析器[默认视图解析器]--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--配置属性suffix 和 prefix--><property name="prefix" value="/WEB-INF/pages/"/><property name="suffix" value=".jsp"/><!--调整优先级--><property name="order" value="10"/></bean><!--解读1. 配置自定义视图解析器BeanNameViewResolver2. BeanNameViewResolver可以去解析我们自定义的视图3. 配置 属性 order, 表示视图解析器执行的顺序, 值越小, 优先级越高4. 属性 order 的默认值是最低优先级 ,值为 Integer.MAX_VALUEint LOWEST_PRECEDENCE = 2147483647--><bean class="org.springframework.web.servlet.view.BeanNameViewResolver"><property name="order" value="99"/></bean><!-- 配置国际化错误信息的资源处理bean --><bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"><!-- 配置国际化文件名字如果你这样配的话,表示messageSource回到 src/i18nXXX.properties去读取错误信息--><property name="basename" value="i18n"></property></bean><!--配置文件上传需要的bean--><bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver"id="multipartResolver"/><!--配置自定义拦截器-spring配置文件--><mvc:interceptors><!--解读1. 第一种配置方式2. 使用ref 引用到对应的myInterceptor013. 这种方式,会拦截所有的目标方法--><!--<ref bean="myInterceptor01"/>--><!--解读1. 第二种配置方式2. mvc:mapping path="/hi" 指定要拦截的路径3. ref bean="myInterceptor01" 指定对哪个拦截器进行配置-->
<!--        <mvc:interceptor>-->
<!--            <mvc:mapping path="/hi"/>-->
<!--            <ref bean="myInterceptor01"/>-->
<!--        </mvc:interceptor>--><!--解读1. 第3种配置方式2. mvc:mapping path="/h*" 通配符方式 表示拦截 /h 打头的路径3. mvc:exclude-mapping path="/hello" /hello不拦截4. ref bean="myInterceptor01" 指定对哪个拦截器配置--><mvc:interceptor><mvc:mapping path="/h*"/><mvc:exclude-mapping path="/hello"/><ref bean="myInterceptor01"/></mvc:interceptor><!--解读1.配置的第二个拦截器2.多个拦截器在执行时,是顺序执行--><mvc:interceptor><mvc:mapping path="/h*"/><ref bean="myInterceptor02"/></mvc:interceptor></mvc:interceptors><!--配置统一处理异常Bean--><bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><prop key="java.lang.ArrayIndexOutOfBoundsException">arrEx</prop><!--<prop key="java.lang.Exception">allEx</prop>--></props></property></bean><!--加入两个常规配置--><!--支持SpringMVC的高级功能,比如JSR303校验, 映射动态请求--><mvc:annotation-driven></mvc:annotation-driven>
<!--    将springmvc不能处理的请求,交给tomcat处理,比如css, js--><mvc:default-servlet-handler/>
</beans>

😄总结

在本文中,我们深入研究了Spring MVC的异常处理机制,从局部异常处理到全局异常处理,再到通过SimpleMappingExceptionResolver进行统一处理,我们详细介绍了每种方法的配置和使用。异常处理在软件开发中扮演着守护者的角色,它可以让我们更好地掌控程序在各种情况下的行为,提高系统的健壮性和可维护性。

无论是在局部还是全局,合适的异常处理都能帮助我们更好地处理潜在的问题,使用户能够获得友好的错误提示,同时也为开发者提供了定位和解决问题的线索。掌握Spring MVC异常处理的技巧,将为您的项目增添一层安全防护,让用户体验更加顺畅,系统更加可靠。希望本文对您理解异常处理的重要性,以及如何在Spring MVC中高效地应用异常处理策略提供了有益的指导。

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

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

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

相关文章

Qt/C++编写视频监控系统80-远程回放视频流

一、前言 远程回放NVR或者服务器上的视频文件&#xff0c;一般有三种方式&#xff0c;第一种是调用厂家的SDK&#xff0c;这个功能最全&#xff0c;但是缺点明显就是每个厂家的设备都有自己的SDK&#xff0c;只兼容自家的设备&#xff0c;如果你的软件需要接入多个厂家的&…

【深入解读Redis系列】Redis系列(五):切片集群详解

首发博客地址 https://blog.zysicyj.top/ 系列文章地址[1] 如果 Redis 内存很大怎么办&#xff1f; 假设一台 32G 内存的服务器部署了一个 Redis&#xff0c;内存占用了 25G&#xff0c;会发生什么&#xff1f; 此时最明显的表现是 Redis 的响应变慢&#xff0c;甚至非常慢。 这…

分类预测 | MATLAB实现SSA-CNN-SVM基于麻雀算法优化卷积支持向量机分类预测

分类预测 | MATLAB实现SSA-CNN-SVM基于麻雀算法优化卷积支持向量机分类预测 目录 分类预测 | MATLAB实现SSA-CNN-SVM基于麻雀算法优化卷积支持向量机分类预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现SSA-CNN-SVM基于麻雀算法优化卷积支持向量机分类预测…

解决selenium的getdrive()方法阻塞问题

selenium里面的Webdriver的get()方法默认是阻塞的&#xff0c;也就是说要等整个页面全都加载完它才会相应。但我们大部分时候不需要用到页面里的所有东西&#xff0c;也许只需要用到里面的一个元素就行了 所以下面是我的解决方法&#xff1a; 初始化代码&#xff1a; # 设置…

perl 语言中 AUTOLOAD 的用法

这里的 AUTOLOAD可以理解为自动加载。具体来说就是&#xff0c;在正常情况下&#xff0c;我们不能调用一个尚未定义的函数&#xff08;子例程&#xff09;。不过&#xff0c;如果在未定义函数的包中有一个名为 AUTOLOAD的函数&#xff0c;那么对未定义函数的调用都会路由至这个…

数学建模:数据的预处理

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 文章目录 数据预处理数据变换数据清洗缺失值处理异常值处理 数据预处理 数据变换 常见的数据变换的方式&#xff1a;通过某些简单的函数进行数据变换。 x ′ x 2 x ′ x x ′ log ⁡ ( x ) ∇ f ( x k )…

Linux中的scp指令

在Linux和Unix系统中&#xff0c;scp&#xff08;Secure Copy Protocol&#xff09;是一个用于通过SSH协议进行安全文件传输的命令行实用程序。与传统的cp&#xff08;copy&#xff09;命令不同&#xff0c;scp允许用户在不同的机器之间、或同一台机器的不同位置之间传输文件或…

Redis 持久化和发布订阅

一、持久化 Redis 是内存数据库&#xff0c;如果不将内存中的数据库状态保存到磁盘&#xff0c;那么一旦服务器进程退出&#xff0c;服务器中的数据库状态也会消失。所以 Redis 提供了持久化功能&#xff01; 1.1、RDB&#xff08;Redis DataBase&#xff09; 1.1.1 …

重仓“AI”的百度迎来收获季?

今年以来&#xff0c;由AIGC引发的“行业旋风”持续席卷各行各业&#xff0c;给沉闷已久的互联网赛道带来了一股暖流。这场AI旋风对于重仓押注AI的玩家而言&#xff0c;更是如同“久旱逢甘霖”&#xff0c;终于迎来了“柳暗花明”的一天。 作为重仓押注AI赛道的头部玩家&#x…

oracle 创建数据库

查询表空间的命令 select t1.name,t2.name from v$tablespace t1,v$datafile t2 where t1.ts# t2.ts#; CREATE TABLESPACE ORM_342_BETA DATAFILE /app/oracle/oradata/sysware/ORM_342_BETA.DBF size 800M --存储地址 初始大小800M autoextend on nex…

第一方支付、第二方支付、第三方支付、第三方支付是什么?

我相信关于支付行业大家多多少少都有一些自己的理解&#xff0c;但是具体的一些名词如标题中的这些&#xff0c;第一方、第二方、第三方支付&#xff0c;到底指的是什么&#xff1f; 第一方支付 也就是现金支付&#xff0c;其本质的意义就是指货币支付&#xff0c;从最早出现货…

猜拳游戏小程序源码 大转盘积分游戏小程序源码 积分游戏小程序源码

简介&#xff1a; 猜拳游戏大转盘积分游戏小程序前端模板源码&#xff0c;一共五个静态页面&#xff0c;首页、任务列表、大转盘和猜拳等五个页面 图片&#xff1a;

[pytorch]torch.cuda用法以及判断显卡是不是存在问题

常见用法&#xff1a; torch.cuda.is_available() # 查看是否有可用GPU torch.cuda.device_count() # 查看GPU数量 torch.cuda.get_device_capability(device) # 查看指定GPU容量 torch.cuda.get_device_name(device) # 查看指定GPU名称 torch.cuda.empty_cache() # 清空程序占…

gitlab配置备忘

版本 gitlab 14.6.2 gitlab备份上传到阿里云oss ### Backup Settings ###! Docs: https://docs.gitlab.com/omnibus/settings/backups.html# gitlab_rails[manage_backup_path] true # gitlab_rails[backup_path] "/var/opt/gitlab/backups"###! Docs: https://…

Linux学习--Ceph部署

前期准备 资源下载 链接: https://pan.baidu.com/s/1Yof-X-fD8kYLSmLAWFo5Ug 提取码: txj5 环境准备 主机名 IP地址 ceph1 192.168.88.11/24 ceph2 192.168.88.12/24 ceph3 192.168.88.13/24 client1 192.168.88.10/24 pubserver 192.168.88.240/24在pubserver上配置ansible…

Spring与Mybatis集成且Aop整合

目录 一、集成 1.1 集成的概述 1.2 集成的优点 1.3 代码示例 二、整合 2.1 整合概述 2.2 整合进行分页 一、集成 1.1 集成的概述 集成是指将不同的组件、部分或系统组合在一起&#xff0c;以形成一个整体功能完整的解决方案。它是通过连接、交互和协调组件之间的关系来实…

MybatisPlus-插件篇

文章目录 一、前言二、插件1、分页插件2.1.1、引入依赖2.1.1、配置分页插件2.1.3、使用分页方法 2、乐观锁插件2.1、引入依赖2.2、添加版本字段2.3、配置乐观锁插件2.4、执行更新操作 三、总结 一、前言 本文将详细介绍mybatisplus中常用插件的使用。 二、插件 1、分页插件 …

《算法竞赛·快冲300题》每日一题:“x1 == x2”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ x…

ADC介绍

简介&#xff1a; Successive Approximation ADC&#xff08;SAR ADC&#xff09;&#xff1a;逐次逼近ADC&#xff0c;SAR ADC。 主要用于测量电压信号。特性如下&#xff08;来自公开资料&#xff09;&#xff1a; 10bits resolutionUp to 1MS/s sampling rate4 single-en…

Texlive2023与Texstudio2023卸载与安装(详细全程)

早在两年前安装了texlive2020&#xff0c;最近重新使用总是报错&#xff0c;好像是因为版本过低。我就找了个时间更新一下texlive版本&#xff0c;全程如下。 1、卸载texlive老版本 1&#xff09;找到texlive目录&#xff0c;比如我的是D:\texlive\2022\tlpkg\installer&…