Spring MVC统一异常处理的3种方式(附带实例)

news/2024/5/20 1:55:03/文章来源:https://blog.csdn.net/unbelievevc/article/details/128159875

在 Spring MVC 应用的开发中,不管是对底层数据库操作,还是业务层或控制层操作,都会不可避免地遇到各种可预知的、不可预知的异常需要处理。

如果每个过程都单独处理异常,那么系统的代码耦合度高,工作量大且不好统一,以后维护的工作量也很大。

如果能将所有类型的异常处理从各层中解耦出来,这样既保证了相关处理过程的功能单一,又实现了异常信息的统一处理和维护。

幸运的是,Spring MVC 框架支持这样的实现。Spring MVC 统一异常处理有以下 3 种方式:

  • 使用 Spring MVC 提供的简单异常处理器 SimpleMappingExceptionResolver。
  • 实现 Spring 的异常处理接口 HandlerExceptionResolver 自定义自己的异常处理器。
  • 使用 @ExceptionHandler 注解实现异常处理

本节主要根据这 3 种处理方式讲解 Spring MVC 应用的异常统一处理。

为了验证 Spring MVC 框架的 3 种异常处理方式的实际效果,需要开发一个测试应用 springMVCDemo10,从 Dao 层、Service 层、Controller 层分别抛出不同的异常(SQLException、自定义异常和未知异常),然后分别集成 3 种方式进行异常处理,进而比较其优缺点。springMVCDemo10 应用的结构如图 1 所示。


图 1 springMVCDemo10应用的结构

3 种异常处理方式的相似部分有 Dao 层、Service 层、View 层、MyException、TestException Controller 以及 web.xml,下面分别介绍这些相似部分。

1)创建应用 springMVCDemo10

创建应用 springMVCDemo10,并导入 Spring MVC 相关的 JAR 包。

2)创建自定义异常类

在 src 目录下创建 exception 包,并在该包中创建自定义异常类 MyException。具体代码如下:

  1. package exception;
  2. public class MyException extends Exception {
  3. private static final long serialVersionUID = 1L;
  4. public MyException() {
  5. super();
  6. }
  7. public MyException(String message) {
  8. super(message);
  9. }
  10. }

3)创建 Dao 层

在 src 目录下创建 dao 包,并在该包中创建 TestExceptionDao 类,在该类中定义 3 个方法,分别抛出“数据库异常”“自定义异常”和“未知异常”。具体代码如下:

  1. package dao;
  2. import java.sql.SQLException;
  3. import org.springframework.stereotype.Repository;
  4. @Repository("TestExceptionDao")
  5. public class TestExceptionDao {
  6. public void daodb() throws Exception {
  7. throw new SQLException("Dao中数据库异常");
  8. }
  9. public void daomy() throws Exception {
  10. throw new SQLException("Dao中自定义异常");
  11. }
  12. public void daono() throws Exception {
  13. throw new SQLException("Dao中未知异常");
  14. }
  15. }

4)创建 Service 层

在 src 目录下创建 service 包,并在该包中创建 TestExceptionService 接口和 TestExceptionServiceImpl 实现类,在该接口中定义 6 个方法,其中有 3 个方法调用 Dao 层中的方法,有 3 个是 Service 层的方法。

Service 层的方法是为演示 Service 层的“数据库异常”“自定义异常”和“未知异常”而定义的。

TestExceptionService 接口的代码如下:

  1. package service;
  2. public interface TestExceptionService {
  3. public void servicemy() throws Exception;
  4. public void servicedb() throws Exception;
  5. public void daomy() throws Exception;
  6. public void daodb() throws Exception;
  7. public void serviceno() throws Exception;
  8. public void daono() throws Exception;
  9. }

TestExceptionServiceImpl 实现类的代码如下:

  1. package service;
  2. import java.sql.SQLException;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Service;
  5. import dao.TestExceptionDao;
  6. import exception.MyException;
  7. @Service("testExceptionService")
  8. public class TestExceptionServiceImpl implements TestExceptionService {
  9. @Autowired
  10. private TestExceptionDao testExceptionDao;
  11. @Override
  12. public void servicemy() throws Exception {
  13. throw new MyException("Service中自定义异常");
  14. }
  15. @Override
  16. public void servicedb() throws Exception {
  17. throw new SQLException("Service中数据库异常");
  18. }
  19. @Override
  20. public void daomy() throws Exception {
  21. testExceptionDao.daomy();
  22. }
  23. @Override
  24. public void daodb() throws Exception {
  25. testExceptionDao.daodb();
  26. }
  27. @Override
  28. public void serviceno() throws Exception {
  29. throw new SQLException("Service中未知异常");
  30. }
  31. @Override
  32. public void daono() throws Exception {
  33. testExceptionDao.daono();
  34. }
  35. }

5)创建控制器类

在 src 目录下创建 controller 包,并在该包中创建 TestExceptionController 控制器类,代码如下:

  1. package controller;
  2. import java.sql.SQLException;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import service.TestExceptionService;
  7. import exception.MyException;
  8. @Controller
  9. public class TestExceptionController {
  10. @Autowired
  11. private TestExceptionService testExceptionService;
  12. @RequestMapping("/db")
  13. public void db() throws Exception {
  14. throw new SQLException("控制器中数据库异常");
  15. }
  16. @RequestMapping("/my")
  17. public void my() throws Exception {
  18. throw new MyException("控制器中自定义异常");
  19. }
  20. @RequestMapping("/no")
  21. public void no() throws Exception {
  22. throw new Exception("控制器中未知异常");
  23. }
  24. @RequestMapping("/servicedb")
  25. public void servicedb() throws Exception {
  26. testExceptionService.servicedb();
  27. }
  28. @RequestMapping("/servicemy")
  29. public void servicemy() throws Exception {
  30. testExceptionService.servicemy();
  31. }
  32. @RequestMapping("/serviceno")
  33. public void serviceno() throws Exception {
  34. testExceptionService.serviceno();
  35. }
  36. @RequestMapping("/daodb")
  37. public void daodb() throws Exception {
  38. testExceptionService.daodb();
  39. }
  40. @RequestMapping("/daomy")
  41. public void daomy() throws Exception {
  42. testExceptionService.daomy();
  43. }
  44. @RequestMapping("/daono")
  45. public void daono() throws Exception {
  46. testExceptionService.daono();
  47. }
  48. }

6)创建 View 层

View 层中共有 5 个 JSP 页面,下面分别介绍。

测试应用首页面 index.jsp 的代码如下:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <h1>所有的演示例子</h1>
  12. <h3><a href="${pageContext.request.contextPath }/daodb"> 处理dao中数据库异常</a></h3>
  13. <h3><a href="${pageContext.request.contextPath }/daomy"> 处理dao中自定义异常</a></h3>
  14. <h3><a href="${pageContext.request.contextPath }/daono"> 处理dao未知错误 </a></h3>
  15. <hr>
  16. <h3><a href="${pageContext.request.contextPath }/servicedb">处理 service中数据库异常</a></h3>
  17. <h3><a href="${pageContext.request.contextPath }/servicemy">处理 service中自定义异常</a></h3>
  18. <h3><a href="${pageContext.request.contextPath }/serviceno">处理 service未知错误</a></h3>
  19. <hr>
  20. <h3><a href="${pageContext.request.contextPath }/db">处理 controller中数据库异常</a></h3>
  21. <h3><a href="${pageContext.request.contextPath }/my">处理 controller中自定义异常</a></h3>
  22. <h3><a href="${pageContext.request.contextPath }/no">处理 controller未知错误</a></h3>
  23. <hr>
  24. <!-- 在 web.xml中配置404 -->
  25. <h3>
  26. <a href="${pageContext.request.contextPath }/404">404 错误</a>
  27. </h3>
  28. </body>
  29. </html>

404 错误对应页面 404.jsp 的代码如下:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. 资源已不在。
  12. </body>
  13. </html>

未知异常对应页面 error.jsp 的代码如下:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8" isErrorPage="true"%>
  3. <%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <H1>未知错误:</H1><%=exception %>
  12. <H2>错误内容:</H2>
  13. <%
  14. exception.printStackTrace(response.getWriter());
  15. %>
  16. </body>
  17. </html>

自定义异常对应页面 my-error.jsp 的代码如下:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8" isErrorPage="true"%>
  3. <%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <H1>自定义异常错误:</H1><%=exception %>
  12. <H2>错误内容:</H2>
  13. <%
  14. exception.printStackTrace(response.getWriter());
  15. %>
  16. </body>
  17. </html>

SQL 异常对应页面 sql-error.jsp 的代码如下:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8" isErrorPage="true"%>
  3. <%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <H1>数据库异常错误:</H1><%=exception %>
  12. <H2>错误内容:</H2>
  13. <%
  14. exception.printStackTrace(response.getWriter());
  15. %>
  16. </body>
  17. </html>

7)web.xml

对于 Unchecked Exception 而言,由于代码不强制捕获,往往被忽略,如果运行期产生了 Unchecked Exception,而代码中又没有进行相应的捕获和处理,则可能不得不面对 404、500 等服务器内部错误提示页面,所以在 web.xml 文件中添加了全局异常 404 处理。具体代码如下:

  1. <error-page>
  2. <error-code>404</error-code>
  3. <location>/WEB-INF/jsp/404.jsp</location>
  4. </error-page>

从上述 Dao 层、Service 层以及 Controller 层的代码中可以看出,它们只管通过 throw 和 throws 语句抛出异常,并不处理。下面分别从 3 种方式统一处理这些异常。

由于篇幅有限,分成 3 节对这 3 种方式进行详细讲解,点击下面链接进行阅读:

  • Spring MVC使用SimpleMappingExceptionResolver类异常处理
  • Spring MVC使用HandlerExceptionResolver接口异常处理
  • Spring MVC使用@ExceptionHandler注解异常处理

 

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

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

相关文章

SAS,Stata,HLM,R,SPSS和Mplus分层线性模型HLM分析学生受欢迎程度数据

全文链接&#xff1a;http://tecdat.cn/?p10809本文用于比较六个不同统计软件程序&#xff08;SAS&#xff0c;Stata&#xff0c;HLM&#xff0c;R&#xff0c;SPSS和Mplus&#xff09;的两级分层线性模型的过程和输出&#xff08;点击文末“阅读原文”获取完整代码数据&#…

2021.06青少年软件编程(Python)等级考试试卷(三级)

2021.06青少年软件编程(Python)等级考试试卷(三级) 一、单选题(共25题,每题2分,共50分) 1.关于open()函数的参数,下列描述正确的是?( D ) A. "w+" 以十六进制格式打开一个文件只用于写入 B. "r+"打开一个文件用于读写。文件指针将会放在文件…

视觉SLAM十四讲ch4笔记——李群与李代数

文章目录视觉SLAM十四讲ch4——李群与李代数4.1 李群李代数基础4.2 指数映射和对数映射4.2.1 so(3)↔SO(3)so(3) \leftrightarrow SO(3)so(3)↔SO(3)4.2.2 se(3)↔SE(3)se(3) \leftrightarrow SE(3)se(3)↔SE(3)4.2.3 小总结&#xff1a;so(3)↔SO(3)so(3) \leftrightarrow SO(…

slam学习 - 基本VO代码学习

本打算学习 orb -slam3 源码&#xff0c;但还是先把《slam 14》上的代码看完再说&#xff0c;至少把整个流程走一遍。 相关参考 https://blog.csdn.net/weixin_44684139/article/details/105305564 https://blog.csdn.net/qq_35590091/article/details/97111744 代码需求分析…

耗时大半个月收整全套「Java架构进阶pdf」

花了我大半个月时间收整了全套的「Java架构进阶pdf」&#xff0c;这一波下来&#xff0c;刷完你就会知道&#xff0c;真真香啊&#xff0c;我的心血果然&#xff0c;没白费&#xff01; 请注意&#xff1a;关于全套的「Java架构进阶pdf」&#xff0c;我会从面试-筑基-框架-分布…

npm vue 路由之一级路由(npm默认已经集成了vue)

npm vue 路由之一级路由&#xff08;npm默认已经集成了vue&#xff09; 文档https://v3.router.vuejs.org/zh/installation.html npm install vue-router3.5.2 --save 1.在App.vue上面添加 <router-view></router-view>2.在main.js上面添加 import VueRouter fro…

Lattice库联合ModelSim仿真FIFO

Lattice联合ModelSim仿真FIFO前言一、添加IP二、库文件添加&#xff08;一&#xff09;方式一&#xff1a;添加器件库到ModelSim&#xff08;二&#xff09;方法二&#xff1a;直接添加器件库到Libray,和tb.v在同一个目录下仿真三、仿真&#xff08;一&#xff09;仿真文件&…

[附源码]Python计算机毕业设计Django基于java的社区管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

计网个人作业03

R14. True or false? a a. Suppose Host A is sending a large file to Host B over a TCP connection. If the sequence number for a segment of this connection is m, then the sequence number for the subsequent segment will necessarily be m 1. 假设主机A通过一…

世界连续动作预测模型-方向模型

🍿*★,*:.☆欢迎您/$:*.★* 🍿 正文 <

[附源码]JAVA毕业设计家庭理财管理系统(系统+LW)

[附源码]JAVA毕业设计家庭理财管理系统&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

[附源码]计算机毕业设计医院挂号住院管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]计算机毕业设计学生在线考试系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]计算机毕业设计医疗器械公司公告管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]JAVA毕业设计健身房管理系统(系统+LW)

[附源码]JAVA毕业设计健身房管理系统&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&a…

python使用opencv画圣诞树和画小星星函数

画星星函数&#xff1a; #img 图片 #x y 坐标 #size 大小 def darw_star(img,x,y,color,size40):poly_linenp.array([[x, y-size], [xint(size/4), y-int(size/4)], [xsize, y-int(size/4)],[xint(0.375*size),yint(size/4)],[xsize,ysize],\[x,yint(0.625*size)],[x-size,ysi…

uni-app入门:自定义tabbar

本文介绍如何使用vant Weapp定义自定义tabbar.按照自定义图标的方式进行添加: 自定义tabbar微信官方链接: https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html 1.导入vant weapp并构建npm 项目根目录右键选择外部终端窗口中打开 …

VS系列多通道无线采发仪

VS101/104/208/416/432 是以振弦、温度传感信号为主的多通道无线采发仪&#xff0c;并可扩展其它模拟&#xff08;电流、 电压、电阻&#xff09;信号和数字信号&#xff08;RS485、RS232&#xff09;传感器通道&#xff0c;内置电池&#xff0c;可外接太阳能电池板。最多可实…

【学习记录】Dynaslam源代码魔改-替换MaskRCNN为YoloV5

这两天接了个小任务&#xff0c;需求是替换Dynaslam里面的动态物体识别模块&#xff0c;将MaskRCNN换为YoloV5&#xff0c;这里记录一下过程中遇见的问题。 一、运行Dynaslam Dynaslam本身是一个基于ORBSLAM2的视觉SLAM框架&#xff0c;论文并没有仔细看过&#xff0c;简单来…

期末测试——H5方式练习题

期末考试——H5完成方式——练习题 前言 本练习训练了孩子们的栅格化布局&#xff0c;H5标签&#xff0c;CSS样式&#xff0c;并对列表与菜单进行了强化训练。使孩子们更好的掌握H5布局&#xff0c;为后面的框架教学打好基础。 素材下载地址&#xff1a; 链接&#xff1a;htt…