SpringMVC系列十一: 文件上传与自定义拦截器

文章目录

  • SpringMVC文件上传
    • 基本介绍
    • 需求分析 / 图解
    • 应用实例-代码实现
  • 自定义拦截器
    • 什么是拦截器
    • 自定义拦截器执行流程分析图
    • 自定义拦截器应用实例
      • 快速入门
      • 注意事项和细节
      • Debug执行流程
    • 多个拦截器
      • 多个拦截器执行流程示意图
      • 应用实例1
        • 代码实现
        • 注意事项和细节
      • 应用实例2
    • 作业布置

上一讲, 我们学习的是 SpringMVC系列十: 中文乱码处理与JSON处理

现在打开springmvc项目

在这里插入图片描述

SpringMVC文件上传

基本介绍

1.Spring MVC 为文件上传提供了直接的支持, 这种支持是通过即插即用的 MultipartResolver 实现的. SpringJakata Commons FileUpload 技术实现了一个 MultipartResolver 实现类: CommonsMultipartResolver

2.SpringMVC 上下文中默认没有装配 Multipartresolver, 因此默认情况下不能处理文件的上传工作, 如果想使用 Spring 的文件上传功能, 需现在上下文中配置 MultipartResolver

需求分析 / 图解

在这里插入图片描述

应用实例-代码实现

1.引入springmvc文件上传需要的jar包 spingmvc上传文件需要的jar
在这里插入图片描述

2.在web路径下创建fileUpload.jsp

<body>
<h1>文件上传的演示</h1>
<form action="?" method="post" enctype="multipart/form-data">文件介绍:<input type="text" name="introduce"/><br/>选择文件:<input type="file" name="file"/><br/><input type="submit" value="上传文件"/>
</form>
</body>

3.配置文件过滤器, 在web.xml中, 使用Spring提供的, 前面已经配置过了 传送

4.配置文件上传解析器, 在springDispatcherServlet-servlet.xml, 简单看一下CommonsMultipartResolver源码

<!--配置文件上传需要的bean-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

5.在com.zzw.web.fileupload下新建FileUploadHandler.java

* @author 赵志伟* @version 1.0* 处理文件上传的handler*/
@SuppressWarnings({"all"})
@Controller
public class FileUploadHandler {//编写方法, 处理文件上传的请求@RequestMapping(value = "/fileUpload")public String fileUpload(@RequestParam(value = "file") MultipartFile file,HttpServletRequest request, String introduce) throws IOException {//接收到提交的文件名String originalFilename = file.getOriginalFilename();System.out.println("你上传的文件名=" + originalFilename);System.out.println("文件的介绍=" + introduce);//得到要把上传的文件保存到哪个路径[全路径: 包括文件名]String fileFullPath =request.getServletContext().getRealPath("/img/" + originalFilename);//创建文件File saveToFile = new File(fileFullPath);//将上传的文件, 转存到saveToFilefile.transferTo(saveToFile);return "success";}
}

6.回填``fileUpload.jspaction`

<form action="<%=request.getServletContext()%>/fileUpload" method="post" enctype="multipart/form-data">

7.完成测试[页面方式], 看文件是否成功上传 http://localhost:8088/springmvc/fileUpload.jsp

在这里插入图片描述

在这里插入图片描述

简单地debug一下transferTo()

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

8.完成测试[postman方式]

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

自定义拦截器

什么是拦截器

●说明
1.Spring MVC也可以使用拦截器对请求进行拦截处理, 用户可以自定义拦截器来实现特定的功能.
2.自定义的拦截器必须实现HandlerInterceptor接口

●自定义拦截器的三个方法
1.preHandle(): 这个方法在业务处理器处理请求之前被调用, 在该方法中对用户请求 request 进行处理.
2.postHandler(): 这个方法在目标方法处理完请求后执行
3.afterCompletion(): 这个方法在完全处理完请求后被调用, 可以在该方法中进行一些资源清理的操作.

自定义拦截器执行流程分析图

在这里插入图片描述

●自定义拦截器执行流程说明
1.如果 preHandle 方法, 返回 false, 则不再执行目标方法, 可以在此指定返回页面
2.postHandle 在目标方法被执行后执行, 可以在方法中访问到目标方法返回的 ModelAndView 对象
3.若 preHandle 返回 true, 则 afterCompletion 方法, 在渲染视图之后被执行
4.若 preHandle 返回 false, 则 afterCompletion 方法不会被调用
5.在配置拦截器时, 可以指定该拦截器对哪些请求生效, 哪些请求不生效

自定义拦截器应用实例

快速入门

●应用实例需求
完成一个自定义拦截器, 学习一下如何配置拦截器和拦截器的运行流程

●应用实例-代码实现
1.com.zzw.web.interceptor包下新建MyInterceptor01.java

@Component
public class MyInterceptor01 implements HandlerInterceptor {/*** 解读* 1. preHandle() 在目标方法执行前被执行* 2. 如果preHandle() 返回false, 不再执行目标方法* 3. 该方法可以获取到request, response, handler* 4. 这里根据业务, 可以进行拦截, 并指定跳转到哪个页面** @param request  current HTTP request* @param response current HTTP response* @param handler  chosen handler to execute, for type and/or instance evaluation* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("--MyInterceptor01-- preHandle() 被执行...");return true;}/*** 解读* 1. 在目标方法执行后, 会执行postHandle* 2. 该方法可以获取到 目标方法, 返回的ModelAndView** @param request      current HTTP request* @param response     current HTTP response* @param handler      the handler (or {@link HandlerMethod}) that started asynchronous*                     execution, for type and/or instance examination* @param modelAndView the {@code ModelAndView} that the handler returned*                     (can also be {@code null})* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("--MyInterceptor01-- postHandle()被执行...");}/*** 解读* 1. afterCompletion() 在视图渲染后被执行, 这里可以进行资源清理工作* 2.** @param request  current HTTP request* @param response current HTTP response* @param handler  the handler (or {@link HandlerMethod}) that started asynchronous*                 execution, for type and/or instance examination* @param ex       any exception thrown on handler execution, if any; this does not*                 include exceptions that have been handled through an exception resolver* @throws Exception*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("--MyInterceptor01-- afterCompletion()被执行...");}
}

2.在springDispatcherServlet-servlet.xml 配置拦截器

注意: 拦截器是由spring管理的 ; 过滤器是由web.xml管理的

<!--配置自定义拦截器-spring配置文件-->
<mvc:interceptors><!--解读1. 第一种配置方式2. 使用ref 引用到对应的拦截器myInterceptor013. 这种方式, 会拦截所有的目标方法--><ref bean="myInterceptor01"/>
</mvc:interceptors><!--加入两个常规配置-->
<!--支持SpringMVC的高级功能, 比如JSR303校验, 映射动态请求-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--将springmvc不能处理的请求, 交给tomcat处理, 比如css, js-->
<mvc:default-servlet-handler/>

3.在com.zzw.ewb.interceptor包 下新建FurnHandler.java

@Controller
public class FurnHandler {@RequestMapping(value = "/hi")public String hi() {System.out.println("--FurnHandler-- hi()...");return "success";}@RequestMapping(value = "/hello")public String hello() {System.out.println("--FurnHandler-- hello()...");return "success";}
}

4.web路径下创建interceptor.jsp

<head><title>测试自定义拦截器</title>
</head>
<body>
<h1>测试自定义拦截器</h1>
<a href="<%=request.getContextPath()%>/hi">测试自定义拦截器-hi</a><br/><br/>
<a href="<%=request.getContextPath()%>>/hello">测试自定义拦截器-hello</a>
</body>

5.测试

浏览器测试 http://localhost:8088/springmvc/interceptor.jsp

在这里插入图片描述
–MyInterceptor01-- preHandle() 被执行…
–FurnHandler-- hi()…
–MyInterceptor01-- postHandle()被执行…
–MyInterceptor01-- afterCompletion()被执行…
 
–MyInterceptor01-- preHandle() 被执行…
–FurnHandler-- hello()…
–MyInterceptor01-- postHandle()被执行…
–MyInterceptor01-- afterCompletion()被执行…

postman测试
在这里插入图片描述
在这里插入图片描述
–MyInterceptor01-- preHandle() 被执行…
–FurnHandler-- hi()…
–MyInterceptor01-- postHandle()被执行…
–MyInterceptor01-- afterCompletion()被执行…
 
–MyInterceptor01-- preHandle() 被执行…
–FurnHandler-- hello()…
–MyInterceptor01-- postHandle()被执行…
–MyInterceptor01-- afterCompletion()被执行…

注意事项和细节

1.默认配置是将所有的目标方法都进行拦截, 也可以指定拦截目标方法, 比如只拦截hi

<!--配置自定义拦截器-spring配置文件-->
<mvc:interceptors><!--解读1. 第二种配置方式2. mvc:mapping path="/hi" 指定要拦截的路径3. ref bean="myInterceptor01" 指定对哪个拦截器进行配置--><mvc:interceptor><mvc:mapping path="/hi"/><ref bean="myInterceptor01"/></mvc:interceptor>
</mvc:interceptors>

在这里插入图片描述

2.mvc:mapping 支持通配符, 同时指定不对哪些目标方法进行拦截

<!--配置自定义拦截器-spring配置文件-->
<mvc:interceptors><!--解读1. 第三种配置方式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>
</mvc:interceptors>

FurnHandler添加方法

@RequestMapping(value = "/ok")
public String ok() {System.out.println("--FurnHandler-- ok()...");return "success";
}

interceptor.jsp添加标签

<a href="<%=request.getContextPath()%>/ok">测试自定义拦截器-ok</a>

在这里插入图片描述

3.拦截器需要配置才生效, 不配置是不生效的.

4.如果preHandler() 方法返回了false, 就不会执行目标方法(前提是你的目标方法被拦截了), 程序员可以在这里根据业务需要指定跳转页面.

Debug执行流程

1.prehandle()

在这里插入图片描述

在这里插入图片描述

2.目标方法
在这里插入图片描述

3.postHandle()
在这里插入图片描述
视图解析
在这里插入图片描述
一直点下一步
在这里插入图片描述

4.render()
在这里插入图片描述

5.afterCompletion()
在这里插入图片描述

解释一下model数据怎么来的? 用 postman 再走一圈

get请求
在这里插入图片描述
post请求
在这里插入图片描述

断点打到 preHandle

在这里插入图片描述

目标方法

在这里插入图片描述

postHandle

在这里插入图片描述

render

在这里插入图片描述

afterCompletion

在这里插入图片描述

多个拦截器

多个拦截器执行流程示意图

在这里插入图片描述

在这里插入图片描述

应用实例1

代码实现

1.com.zzw.web.interceptor.MyInterceptor02

@Component
public class MyInterceptor02 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {System.out.println("--MyInterceptor02-- preHandle() 被执行...");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response,Object handler, ModelAndView modelAndView) throws Exception {System.out.println("--MyInterceptor02-- postHandle()被执行...");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex) throws Exception {System.out.println("--MyInterceptor02-- afterCompletion()被执行...");}
}

2.配置springDispathcerServlet-servlet.xml

<mvc:interceptors><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>

3.测试
–MyInterceptor01-- preHandle() 被执行…
–MyInterceptor02-- preHandle() 被执行…
–FurnHandler-- hi()…
–MyInterceptor02-- postHandle()被执行…
–MyInterceptor01-- postHandle()被执行…
–MyInterceptor02-- afterCompletion()被执行…
–MyInterceptor01-- afterCompletion()被执行…

注意事项和细节

1.如果第1个拦截器的preHandle()返回false, 后面都不执行
在这里插入图片描述

2.如果第2个拦截器的preHandle()返回false, 就直接执行第1个拦截器的afterCompletion() 方法, 如果拦截器更多, 规则类似.

3.说明: 前面说的规则, 目标方法被拦截是前提

应用实例2

1.需求: 如果用户提交的数据有禁用词(比如 病毒). 则, 在第1个拦截器就返回, 不执行目标方法, 功能效果如图

2.web路径/WEB-INF/pages/warning.jsp

<head><title>警告</title>
</head>
<body>
<h1>不要乱讲话</h1>
</body>

3.修改MyInterceptor01

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {System.out.println("--MyInterceptor01-- preHandle() 被执行...");//获取到用户提交的关键字String keyword = request.getParameter("keyword");if ("病毒".equals(keyword)) {//请求转发到warning.jsp//这里是原生的请求转发, 不是springmvc里的request.getRequestDispatcher("/WEB-INF/pages/warning.jsp").forward(request, response);return false;}System.out.println("得到keyword=" + keyword);return true;
}

3.postman测试
在这里插入图片描述

–MyInterceptor01-- preHandle() 被执行…
得到keyword=赵志伟
–MyInterceptor02-- preHandle() 被执行…
–FurnHandler-- hi()…
–MyInterceptor02-- postHandle()被执行…
–MyInterceptor01-- postHandle()被执行…
–MyInterceptor02-- afterCompletion()被执行…
–MyInterceptor01-- afterCompletion()被执行…

再次测试
在这里插入图片描述

–MyInterceptor01-- preHandle() 被执行…

作业布置

1.把前面我们学过的SpringMVC文件上传, 自定义拦截器和相关代码和案例, 自己写一遍. 一定要自己写一遍, 否则没有印象, 理解不会深入
2.简述SpringMVC自定义拦截器工作流程, 并画出示意图
3.debug自定义拦截器源码, 加深理解(不用每一条语句都debug), 重点是梳理流程.


在这里插入图片描述

下一讲, 我们学习 SpringMVC系列十一: 文件上传与自定义拦截器

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

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

相关文章

Mongodb UPDATE, 使用$position指定向数组中插入新元素的位置

学习mongodb&#xff0c;体会mongodb的每一个使用细节&#xff0c;欢迎阅读威赞的文章。这是威赞发布的第72篇mongodb技术文章&#xff0c;欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题&#xff0c;欢迎在文章下面点个赞&#xff0c;或者关…

HTML 全局属性介绍及示例

HTML 全局属性是一组可以在任何HTML元素中使用的属性。这些属性提供了一种方式来定义元素的通用行为或外观。以下是一些常见的HTML全局属性及其示例。 id id 属性为元素提供了一个唯一的标识符。它不能在 <head>, <html>, <meta>, <script>, <sty…

vue2+echart 树状图节点密集,可滚动鼠标缩放, 尺寸根据节点调整

vue2echart 树状图节点密集&#xff0c;可滚动鼠标缩放&#xff0c; 尺寸根据节点调整 <template><div ref"chart" style"width: 100%; height: 600px;"></div> </template><script> import * as echarts from echarts;exp…

9.2.2 DeepLab系列模型中每一代的创新是什么?是为了解决什么问题?

9.2.2 DeepLab系列模型中每一代的创新是什么&#xff1f;是为了解决什么问题&#xff1f; 前情回顾&#xff1a;9.2.1 简述图像分割中经常用到的编码器-解码器网络结构的设计理念。 DeepLab是Google 团队提出的一系列图像分割算法。 DeepLab v1在2014年被提出&#xff0c;并在…

微信小程序接入lottie动画

1、注意&#xff1a;canvas渲染出来的层级太高&#xff0c;当有弹窗的情况会暴露在弹窗外 模拟器上会有这个问题&#xff0c;线上版本不会有 2、需求 需要把lottie动画在小程序的环境下进行展示 3、什么是lottie动画 由Airbnb开发并开源。允许设计师将复杂的矢量动画导出为…

李宏毅深度学习项目——HW1个人笔记

视频链接 PDF链接 googleColab链接 GoogleColab是一个免费的jupyter notebook&#xff0c;可以用上面的gpu资源进行训练 题目 通过前两天的数据&#xff0c;预测第三天某个人感染新冠的概率 范例 导包 # Numerical Operations import math import numpy as np# Reading/Wr…

欢迎莅临ARCHE-2024,共享智慧档案盛宴!

敬邀参观&#xff01;2024第三届上海国际智慧档案展览会&#xff08;ARCHE-2024&#xff09;将于2024年6月19-21日在上海跨国采购会展中心盛大开幕。深圳市铨顺宏科技有限公司将展示最新的智慧档案技术与解决方案&#xff0c;展位号H010-H011。期待您的光临&#xff0c;共同探索…

String类的默认实现

#pragma once #include <iostream> using namespace std; #include <assert.h>namespace yyqx//为了与库里面的string进行区分 {//仅仅实现一个简单的string&#xff0c;仅仅考虑资源管理深浅拷贝问题class string{public://构造函数string(const char* str):_size…

对比 Axios 和 Fetch:选择最适合的 HTTP 请求方法

在前端开发中&#xff0c;处理 HTTP 请求是一个常见且重要的任务。JavaScript 提供了多种方式来发送网络请求&#xff0c;其中最受欢迎的两种方式分别就是 Fetch API 和 Axios。尽管两者都能完成同样的任务&#xff0c;即从客户端向服务器发送请求并接收响应&#xff0c;但它们…

无线麦克风推荐哪些品牌?一文读懂家用无线麦克风哪个牌子好!

​在这个充满创意与表达的时代&#xff0c;无线领夹麦克风以其独特的魅力&#xff0c;成为了声音创作者们的得力助手。它小巧便携&#xff0c;功能强大&#xff0c;无论是日常拍摄、直播互动还是专业演出&#xff0c;都能轻松应对&#xff0c;让你的声音随时随地清晰传递。那么…

编程精粹—— Microsoft 编写优质无错 C 程序秘诀 04:对程序进行逐步跟踪

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1993 年发布。2013 年推出了 20 周年纪念第二版。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Writing Clean Code ─── Microsoft’s Techniques for Developing》&a…

机器学习专题记录

有偏估计和无偏估计 无偏估计和有偏估计的区别 无偏估计 无偏估计是用样本统计量来估计总体参数时的一种无偏推断。估计量的数学期望等于被估计参数的真实值&#xff0c;则称此估计量为被估计参数的无偏估计&#xff0c;即具有无偏性&#xff0c;是一种用于评价估计量优良性的…

建筑工地通常那种考勤机好用?

建筑工地通常那种考勤机好用&#xff1f; 大量从乡村前往城市的务工者&#xff0c;所从事的多为建筑工程类行业&#xff0c;此种行业对学历与技能的要求不高&#xff0c;而工资水平倒也尚可&#xff0c;正因如此才吸引了众多劳动者。那要怎样管好工地上的项目呢&#xff1f;首要…

1999-2020年各地级市农村居民人均纯收入数据

1999-2020年各地级市农村居民人均纯收入数据 1、时间&#xff1a;1999-2020年 2、指标&#xff1a;年份、城市、农村居民人均纯收入 3、来源&#xff1a;区域年鉴、各省市年鉴 4、范围&#xff1a;地级市&#xff0c;具体每年城市数量参看下文图片&#xff0c;具体城市名单…

智能名片小程序源码系统 销售名片+企业商城 前后端分离+源代码包+搭建部署教程

系统概述 在当今数字化快速发展的时代&#xff0c;传统的商务交流方式逐渐显露出其局限性。为了满足企业和个人更加高效、便捷地展示和推广自身的需求&#xff0c;智能名片小程序源码系统应运而生。这一系统的开发旨在为用户提供一个集销售名片和企业商城于一体的综合性平台&a…

如何将图片转换为向量?(通过DashScope API调用)

本文介绍如何通过模型服务灵积DashScope将图片转换为向量&#xff0c;并入库至向量检索服务。DashVector中进行向量检索。&#xff0c;通过灵活、易用的模型API服务&#xff0c;让各种模态模型的能力&#xff0c;都能方便的为AI开发者所用。通过灵积API&#xff0c;开发者不仅可…

使用 Redis 生成分布式唯一ID

在分布式系统中&#xff0c;生成唯一ID是一个常见的需求。传统的数据库自增ID无法满足分布式系统的需求&#xff0c;因为多个节点可能同时生成ID&#xff0c;容易导致冲突。本文将介绍一种使用 Redis 实现分布式唯一ID的方法&#xff0c;并通过代码示例进行讲解。 一、背景介绍…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 字符串分隔(二)(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 字符串分隔(二)(100分) 🌍 评测功能需要订阅专栏后私信联系…

深入学习html的步骤

推荐的学习步骤&#xff1a; 1. 深入了解HTML基础标签 列表 HTML提供有序列表(<ol>)和无序列表(<ul>)。 <h2>无序列表</h2> <ul><li>项目一</li><li>项目二</li><li>项目三</li> </ul><h2>…

【ssl】启用http2时遇到的重重问题

【背景】 用pyping server传流式数据,必须启用http2,http2又必须有https支持。反复尝试,打破一个个err,最终成功。此篇记录一路上遇到的各类err和解决办法。 【问题和方案】 第一个警告:流式传输必须启用http2或http3(quic) 原本我是用http1.1启动的服务,所以有问题…