SpringMVC学习:四、SpringMVC的高级开发(异常处理器、文件上传、 拦截器)

news2025/1/14 20:16:30

5. SpringMVC的高级开发

5.1 异常处理器

​ springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。

思路:

​ 系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

​ 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ly5zm9rR-1671171663800)(assets/wps1.jpg)]

​ 为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。

package com.suke.exception;

public class UserException extends Exception {
    public UserException() {
    }

    public UserException(String message) {
        super(message);
    }

    public UserException(String message, Throwable cause) {
        super(message, cause);
    }

    public UserException(Throwable cause) {
        super(cause);
    }

    public UserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

​ 系统遇到异常,在程序中手动抛出,dao抛给service、service给controller、controller抛给前端控制器,前端控制器调用全局异常处理器。

​ 全局异常处理器处理思路:

​ 解析出异常类型

​ 如果该 异常类型是系统 自定义的异常,直接取出异常信息,在错误页面展示

​ 如果该 异常类型不是系统 自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)

springmvc提供一个HandlerExceptionResolver接口

public class GlobalExceptionResolver implements HandlerExceptionResolver {
	@Override
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {
		CustomerException cex = null;
		if(ex instanceof CustomerException){
			//如果抛出的是CustomerException,则直接转换
			cex = (CustomerException) ex;
		}else{
			//如果抛出的不是CustomerException异常,则构造一个CustomerException异常,异常信息为"未知错误"
			cex = new CustomerException("未知错误");
		}
		//把错误信息保存到ModelAndView
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("msg", cex.getMessage());
		//设置错误页面
		modelAndView.setViewName("error");
		return modelAndView;
	}
}

全局异常处理器配置:

在springmvc.xml中添加:

<!-- 全局异常处理器:只要实现HandlerExceptionResolver接口的,都是全局异常处理器-->
<bean class="com.suke.exception.GlobalExceptionResolver"></bean>

注意:

​ 如果与业务功能相关的异常,建议在service中抛出异常。

​ 与业务功能没有关系的异常,建议在controller中抛出。

5.2 文件上传

文件上传客户端三要素

  • 表单项type=“file”

  • 表单的提交方式是post

  • 表单的enctype属性是多部分表单形式,及enctype=“multipart/form-data”

<form action="${pageContext.request.contextPath}/testUpload1" method="post" 
enctype="multipart/form-data">
	名称:<input type="text" name="name"><br>
	文件:<input type="file" name="file"><br> 
    <input type="submit" value="提交"><br>
</form>

单文件上传步骤

① 导入fileupload和io依赖

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

② 配置文件上传解析器

<bean id="multipartResolver" 
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!--上传文件总大小--> 
   <property name="maxUploadSize" value="5242800"/>
	<!--上传单个文件的大小--> 
   <property name="maxUploadSizePerFile" value="5242800"/>
	<!--上传文件的编码类型--> 
   <property name="defaultEncoding" value="UTF-8"/>
</bean>

注意:bean的id一定为multipartResolver,否则获取不到数据

③ 编写文件上传代码

@RequestMapping("/testUpload1")
@ResponseBody
public void testUpload1(String name,MultipartFile file) throws 
IOException {
 if(file != null){
   //获得上传文件名文件名称
	String originalFilename = uploadFile.getOriginalFilename();
   String savePath="D:/upload/";
   String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    File saveFile = new File(savePath,new Date().getTime()+suffix); 
	//保存文件
	uploadFile.transferTo(saveFile);
   }
   return "index";
}

在Idea配置虚拟路径

把服务器本地的一个目录, 部署到tomcat, 绑定一个url, 这个url映射是服务器本地的一个目录,

并把url暴露出来, 用户通过网络访问这个url, tomcat根据配置的, 自动找对应服务器本地的一个目录
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

5.3 拦截器

​ Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理后处理。将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。

拦截器和过滤器区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vXtsBsyv-1671171663811)(assets/image-20220821162044233.png)]

自定义拦截器很简单,只有如下三步:

① 创建拦截器类实现HandlerInterceptor接口

public class HandlerInterceptor1 implements HandlerInterceptor {
    /**
	 * controller执行前调用此方法
	 * 返回true表示继续执行,返回false中止执行
	 * 这里可以加入登录校验、权限拦截等
	 */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse 
    response, Object handler) {
    	System.out.println("preHandle running...");
    	return true; 
    }
    /**
	 * controller执行后但未返回视图前调用此方法
	 * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
	 */
    public void postHandle(HttpServletRequest request, HttpServletResponse 
    	response, Object handler, ModelAndView modelAndView) {
    	System.out.println("postHandle running...");
    }
    /**
	 * controller执行后且视图返回后调用此方法
	 * 这里可得到执行controller时的异常信息
	 * 这里可记录操作日志,资源清理等
	 */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse 
    	response, Object handler, Exception ex) {
    	System.out.println("afterCompletion running...");
    } 
}

② 配置拦截器

  • 针对某种mapping配置拦截器

**springmvc拦截器针对HandlerMapping进行拦截设置,**如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该拦截器。

<bean
	class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
	<property name="interceptors">
		<list>
			<ref bean="handlerInterceptor1"/>
		</list>
	</property>
</bean>
<bean id="handlerInterceptor1"class="springmvc.intercapter.HandlerInterceptor1"/>
  • 针对所有mapping配置全局拦截器

    springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。

    <!--拦截器 -->
    <mvc:interceptors>
    	<!--多个拦截器,顺序执行 -->
    	<mvc:interceptor>
    		<!—/**拦截所有的url包括子url -->
    		<mvc:mapping path="/**"/>
    		<bean class="com.suke.interceptor.HandlerInterceptor1"></bean>
    	</mvc:interceptor>
    </mvc:interceptors>
    

③ 测试拦截器的拦截效果

1. 两个拦截器都放行
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle 
HandlerInterceptor2...postHandle
HandlerInterceptor1...postHandle
HandlerInterceptor2...afterCompletion
HandlerInterceptor1...afterCompletion

总结

preHandle方法按顺序执行,

postHandle和afterCompletion按拦截器配置的逆向顺序执行。

2. 拦截器1放行,拦截器2不放行

HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor1...afterCompletion

总结:

拦截器1放行,拦截器2 preHandle才会执行。

拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。

只要有一个拦截器不放行,postHandle不会执行。

  1. 拦截器1不放行,拦截器2不放行
HandlerInterceptor1...preHandle

总结:

拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。

拦截器1 preHandle不放行,拦截器2不执行。

  1. 小结

preHandle按拦截器定义顺序调用

postHandler按拦截器定义逆序调用

afterCompletion按拦截器定义逆序调用

postHandler在拦截器链内所有拦截器返成功调用

afterCompletion只有preHandle返回true才调用

w) {
System.out.println(“postHandle running…”);
}
/**
* controller执行后且视图返回后调用此方法
* 这里可得到执行controller时的异常信息
* 这里可记录操作日志,资源清理等
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse
response, Object handler, Exception ex) {
System.out.println(“afterCompletion running…”);
}
}


② 配置拦截器

-   **针对某种mapping配置拦截器**

  **springmvc拦截器针对HandlerMapping进行拦截设置,**如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该拦截器。

  ```xml
  <bean
  	class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
  	<property name="interceptors">
  		<list>
  			<ref bean="handlerInterceptor1"/>
  		</list>
  	</property>
  </bean>
  <bean id="handlerInterceptor1"class="springmvc.intercapter.HandlerInterceptor1"/>
  • 针对所有mapping配置全局拦截器

    springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。

    <!--拦截器 -->
    <mvc:interceptors>
    	<!--多个拦截器,顺序执行 -->
    	<mvc:interceptor>
    		<!—/**拦截所有的url包括子url -->
    		<mvc:mapping path="/**"/>
    		<bean class="com.suke.interceptor.HandlerInterceptor1"></bean>
    	</mvc:interceptor>
    </mvc:interceptors>
    

③ 测试拦截器的拦截效果

1. 两个拦截器都放行
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle 
HandlerInterceptor2...postHandle
HandlerInterceptor1...postHandle
HandlerInterceptor2...afterCompletion
HandlerInterceptor1...afterCompletion

总结

preHandle方法按顺序执行,

postHandle和afterCompletion按拦截器配置的逆向顺序执行。

2. 拦截器1放行,拦截器2不放行

HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor1...afterCompletion

总结:

拦截器1放行,拦截器2 preHandle才会执行。

拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。

只要有一个拦截器不放行,postHandle不会执行。

  1. 拦截器1不放行,拦截器2不放行
HandlerInterceptor1...preHandle

总结:

拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。

拦截器1 preHandle不放行,拦截器2不执行。

  1. 小结

preHandle按拦截器定义顺序调用

postHandler按拦截器定义逆序调用

afterCompletion按拦截器定义逆序调用

postHandler在拦截器链内所有拦截器返成功调用

afterCompletion只有preHandle返回true才调用

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

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

相关文章

如何利用代理IP做SEO监控优化?

从事互联网营销相关的用户多多少少都会接触到SEO&#xff0c;一般来说企业为了实现传播效果&#xff0c;每天都需要大量重复地做各种渠道的投放&#xff0c;这是一项逐渐累积的长期性工作。而这其中关键的优化分析与监控&#xff0c;势必需要大量的数据支持。接下来就一起来了解…

Linux--seq命令

seq(sequeue)用于序列化输出一个数到另一个数之间的整数&#xff0c;输出连续的数字、 固件间隔的数字、指定格式的数字。 一、使用方法 seq [选项] 尾数seq [选项] 首数 尾数seq [选项] 首数 增量 尾数 [选项] -f, --formatFORMAT use printf style floating-point FO…

深度学习 Day22——利用LSTM实现火灾温度预测

深度学习 Day22——利用LSTM实现火灾温度预测 文章目录深度学习 Day22——利用LSTM实现火灾温度预测一、前言二、我的环境三、LSTM介绍1、长期依赖的问题2、LSTM3、LSTM结构四、前期工作1、设置GPU2、导入数据3、数据可视化五、构建数据集1、设置X、y2、设置归一化3、划分数据集…

[附源码]Nodejs计算机毕业设计基于的校园失物招领平台Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

[附源码]Python计算机毕业设计高校学生综合素质测评系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

分析Linux 内核 SCSI IO 子系统

【推荐阅读】 浅析linux内核网络协议栈--linux bridge virtio-net 实现机制【一】&#xff08;图文并茂&#xff09; 怎么在Windows下使用Makefile文件 概述 LINUX 内核中 SCSI 子系统由 SCSI 上层&#xff0c;中间层和底层驱动模块 [1] 三部分组成&#xff0c;主要负责管…

PreSTU:一个专门为场景文本理解而设计的简单预训练模型

摘要&#xff1a;在视觉与语言&#xff08;V&L&#xff09;模型中&#xff0c;阅读和推理图像中的文本的能力往往是缺乏的。我们如何才能学习出强大的场景文本理解&#xff08;STU&#xff09;的V&L模型呢&#xff1f;本文分享自华为云社区《场景文本理解预训练PreSTU》…

C#编程基础(万字详解,这一篇就够了)

C#及其开发环境简介 C#概述 C#的编程功能 C#与.Net的关系 .Net C# C#的集成开发环境 Windows上编写C#程序 Linux/Mac OS上编写C#程序 运行第一个HelloWorld程序 C#基本语法 程序实例 C#基本语法 using关键字 class关键字 注释 成员变量 成员函数 实例化一个类…

【图像分割】粒子群优化指数熵图像分割【含Matlab源码 287期】

⛄一、图像分割简介 理论知识参考&#xff1a;【基础教程】基于matlab图像处理图像分割【含Matlab源码 191期】 ⛄二、部分源代码 %%无递推 clc; clear; Cimread(‘1.jpg’); Crgb2gray©; %Cimnoise(C,‘gaussian’,0,0.005); figure subplot(1,2,1) imshow© tic …

vue初级入门以及demo实现详解

vue的初级入门1&#xff0c;vue是什么2&#xff0c;vue的特点2.1&#xff0c;采用组件化模式2.2&#xff0c;声明式编码2.3&#xff0c;虚拟DOM Diff算法3&#xff0c;vue的环境的基本配置和使用3.1&#xff0c;在浏览器安装开发工具3.2&#xff0c;开发环境3.3&#xff0c;de…

C++--数据结构--图的相关概念及模拟实现--高阶0712

1. 图的基本概念 图&#xff08;G&#xff09;是由顶点&#xff08;V&#xff09;集合及顶点间的关系&#xff08;边 E&#xff09;组成的一种数据结构&#xff1b; 顶点&#xff1a;图中的结点&#xff0c;第i个顶点记作vi。 两个顶点vi和vj相关称作vi和vj之间有一条边。 …

04查找算法:顺序查找法、二分查找法

开始系统学习算法啦&#xff01;为后面力扣和蓝桥杯的刷题做准备&#xff01;这个专栏将记录自己学习算法是的笔记&#xff0c;包括概念&#xff0c;算法运行过程&#xff0c;以及代码实现&#xff0c;希望能给大家带来帮助&#xff0c;感兴趣的小伙伴欢迎评论区留言或者私信博…

技术分享 | 测试平台开发-前端开发之Vue.js 框架的使用(二)

首先将 Vue.js 下载到本地&#xff0c;本章就以本地的 Vue.js 为例。在本地创建一个工作区即创建一个文件夹&#xff0c;使用 vscode 打开&#xff0c;将 Vue.js 放到工作区目录下。 创建挂载元素 首先创建一个 index.html 的文件&#xff0c;使用 <script src"./vue…

educoder:Numpy图像处理

第1关&#xff1a;图像翻转 任务描述 本关任务&#xff1a;读取一副图片&#xff0c;实现图片的翻转。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.如何读取和保存图像&#xff0c;2.图像的数组表示。 彩色图像 与人脑不同&#xff0c;计算机读入一张…

给视频智能配音怎么弄?一步一步让你学会配音操作

如今我们的生活变得越来越便捷化&#xff0c;因此越来越多的新鲜事物出现在了我们的眼前&#xff0c;例如配音。随着短视频逐渐火爆起来&#xff0c;相信屏幕前的你也剪辑过自己拍摄的视频&#xff0c;并将其发到各大社交平台上吧&#xff01;但是对于视频剪辑来说&#xff0c;…

HTML CSS

一、HTML 介绍 HTML 是一门语言&#xff0c;所有的网页都是用HTML 这门语言编写出来的。HTML(HyperText Markup Language)&#xff1a;超文本标记语言&#xff1a;&#xff08;1&#xff09;超文本&#xff1a;超越了文本的限制&#xff0c;比普通文本更强大。除了文字信息&…

2022 年值得了解的基础设施即代码工具清单

云计算的出现彻底改变了每个 IT 领域。不排除 IT 基础设施。管理员不得不手动配置资源并管理大型 Excel 表格中的数据的日子已经一去不复返了。在当今动态变化的网络需求下&#xff0c;人工维护 IT 基础设施的想法非常可怕。这就是基础设施即代码工具的用武之地。 简单地说&…

【PostgreSQL的“double buffers“刷脏机制和参数】

PostgreSQL数据库使用双缓存写数据&#xff0c;shared_buffer OS page cache,下图是PG与OS内存交互的过程 ,在PostgreSQL中&#xff0c;shared_buffers所代表的内存区域可以看成是一个以8KB的block为单位的数组&#xff0c;即最小的分配单位是8KB。这正好是一个page的大小&…

手慢无,阿里云神作被《Spring Boot进阶原理实战》成功扒下,限时

又来给大家分享好书了&#xff1a;郑天民老师的 《Spring Boot进阶:原理、实战与面试题分析》&#xff0c;别问网上有没有开源版本&#xff01;问就是我也不知道&#xff0c;哈哈&#xff01;但我会有 郑天民是谁&#xff1f; 资深架构师和技术专家&#xff0c;有近15年的软件…

中英文说明书丨艾美捷CD8α体内抗体相关研究方案

艾美捷CD8α体内抗体英文说明&#xff1a; CD8a (Ly 2.2) is present on the surface of most thymocytes and mature T-lymphocyte subsets including most T-suppressor/cytotoxic cells. CD8 participates in T cell activation by binding to T cell receptor complex and…