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);
        //将上传的文件, 转存到saveToFile
        file.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
     */
    @Override
    public 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
     */
    @Override
    public 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
     */
    @Override
    public 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 引用到对应的拦截器myInterceptor01
    3. 这种方式, 会拦截所有的目标方法
    -->
    <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 {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        System.out.println("--MyInterceptor02-- preHandle() 被执行...");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("--MyInterceptor02-- postHandle()被执行...");
    }

    @Override
    public 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系列十一: 文件上传与自定义拦截器

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

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

相关文章

[创业之路-118] :制造业企业的必备管理神器-ERP-制造业的基本方程式与ERP的发展历程,哪些企业需要ERP?

目录 一、制造业的基本方程式 1.1 基本方程式 1.2 制造的数学模型 二、ERP的发展历程 2.1 发展历程 2.2 比较 三、过往产品回顾 3.1 定货点法 3.2 时段式ERP 3.3 闭环式MRP 3.4 ERP 四、哪些企业需要ERP 4.1 概述 4.2 软件企业需要ERP吗&#xff1f; 一、制造业的…

【计算机网络篇】数据链路层(6)共享式以太网_网络适配器_MAC地址

文章目录 &#x1f354;网络适配器&#x1f354;MAC地址&#x1f5d2;️IEEE 802局域网的MAC地址格式&#x1f4d2;IEEE 802局域网的MAC地址发送顺序&#x1f95a;单播MAC地址&#x1f95a;广播MAC地址&#x1f95a;多播MAC地址&#x1f50e;小结 &#x1f354;网络适配器 要将…

汇川h3U用modbus配置扩展IO

扩展IO模块为4个艾莫迅RTU简易版&#xff0c;16输入&#xff0c;16输出。物理连接为RS485&#xff0c;A B两根线。 下面为H3Umodbus配置&#xff0c;关键是协议选择为&#xff1a;MODBUS主站配置。协议配置&#xff1a;和从站保持一致 通过下图的程序及配置&#xff0c;已经可…

VB打开word文档

在编码之前&#xff0c;先安装Microsoft.Office.Interop.Word Imports Microsoft.Office.InteropModule Module1Sub Main() 创建Word应用程序实例Dim wordApp As New Word.Application() 设置为可见wordApp.Visible True 打开指定的Word文档Dim doc As Word.Document wordA…

期货分仓软件的搭建流程

期货分仓软件的搭建流程&#xff0c;是一个涉及多个环节的复杂过程。首先&#xff0c;明确功能需求是至关重要的&#xff0c;这有助于更好地规划软件的开发和设计。接下来&#xff0c;技术选型是关键一步&#xff0c;需要根据开发经验和项目需求&#xff0c;选择适合的编程语言…

maven archetype项目构架

1、设置环境变量 set MAVEN_HOMED:\SF\java\apache-maven-3.6.3 set path%path%;%MAVEN_HOME%\bin;2、制作archetype mvn -s "D:\SF\java\apache-maven-3.6.3\conf\settings.xml" archetype:create-from-project -DpackageNamecom.demo.esb-s:指定maven的setting文…

华为---VLAN-配置Eth-Trunk链路聚合(三)

6.3 配置Eth-Trunk链路聚合 6.3.1 原理概述 在没有使用Eth-Trunk前&#xff0c;百兆以太网的双绞线在两个互连的网络设备间的带宽仅为100Mbit/s。若想达到更高的数据传输速率&#xff0c;则需要更换传输媒介&#xff0c;使用千兆光纤或升级成为千兆以太网。这样的解决方案成本…

肩背筋膜炎怎么治疗最有效

肩背筋膜炎是一种常见的肌肉骨骼疾病&#xff0c;其症状主要包括&#xff1a;肩背区域疼痛&#xff1a;由于筋膜组织受到损伤&#xff0c;肩背部位会出现明显的疼痛&#xff0c;疼痛可能会放射到周围的其他部位&#xff0c;严重时会影响睡眠和休息。肌肉紧张和僵硬&#xff1a;…

【计算机网络仿真实验-实验3.1、3.2】交换路由综合实验

实验3.1 交换路由综合实验——作业1 一、实验目的 运用实验二&#xff08;可前往博主首页计算机网络专栏下查看&#xff09;中学到的知识&#xff0c;将这个图中的PC机连接起来组网并分析&#xff0c;本篇涉及代码以截图展示&#xff0c;过于简单的代码及操作不再详细介绍&…

领航未来!信息技术服务管理体系如何点燃企业数字化转型的“火箭引擎”

在当今这个数字化飞速发展的时代&#xff0c;信息技术已经成为企业运营和管理的核心驱动力。随着企业对于信息化、智能化的需求日益增长&#xff0c;如何构建一套科学、高效的信息技术服务管理体系&#xff0c;不仅关乎企业内部的运营效率&#xff0c;更直接影响着企业的市场竞…

Quantlab整合Alpha158因子集,为机器学习大类资产配置策略做准备(代码+数据)

原创文章第565篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 我们的研报得现工作&#xff0c;用了两篇文章讲数据准备&#xff1a; 【研报复现】年化16.19%&#xff0c;人工智能多因子大类资产配置策略 【研报复现】年化27.1%&#xff0c;人…

有了智能猫砂盆不用手动铲屎了?解放双手的好用品牌分享来了!

在现代都市的忙碌节奏中&#xff0c;许多养猫家庭常常因为需要上班或频繁出差而忙碌不堪。每天早出晚归&#xff0c;甚至有时候还要面临加班和紧急出差的情况&#xff0c;导致很难有足够的时间和精力去及时为猫咪铲屎。然而&#xff0c;猫咪是敏感而干净的动物&#xff0c;它们…

AJAX 综合案例-day2

Bootstrap 弹框 功能&#xff1a;不离开当前页面&#xff0c;显示单独内容&#xff0c;供用户操作 步骤&#xff1a; 1. 引入 bootstrap.css 和 bootstrap.js 2. 准备 弹框标签 &#xff0c;确认结构 3. 通过 自定义属性 &#xff0c;控制弹框的 显示 和 隐藏 1. 通过属性…

Mac M3 Pro 部署Trino-server-449

目录 1、下载安装包 2、解压并设置配置参数 3、启动并验证 4、使用cli客户端连接测试 1、下载安装包 官方&#xff1a;trino-server-449 CLI 网盘&#xff1a; server https://pan.baidu.com/s/16IH-H39iF8Fb-Vd14f7JPA?pwd3vjp 提取码: 3vjp cli https://pan.baidu.…

手把手教你挖赏金系列(2)如何挖掘短信验证码漏洞

免责声明 由于传播、利用本公众号所发布的而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人承担。LK安全公众号及原文章作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担&#xff01;如有侵权烦请告知&#xff0c;我们会立即删除并致歉。谢谢&#…

04. Java 多线程的创建

1. 前言 本节内容重点需要掌握 Java 多线程的三种创建方式&#xff0c;具体内容如下&#xff1a; Java 线程类 Thread 继承结构&#xff0c;这是 JDK Thread 源码的类结构&#xff0c;是了解 Thread 类的第一步&#xff1b;掌握多线程的三种创建方式&#xff0c;这是本节的重…

MySQL第三方图形化工具:DBeaver

操纵数据库的语言&#xff0c;基于功能划分为4类&#xff1a; 数据定义:DDL(Data Definition Language)库的创建删除、表的创建删除等 数据操纵:DML(Data ManipulationLanguage)新增数据、删除数据、修改数据等 数据控制:DCL(Data ControlLanguage)新增用户、删除用户、密码…

Web3新视野:Lumoz节点的潜力与收益解读

摘要&#xff1a;低估值、高回报、无条件退款80%...... Lumoz正通过其 zkVerifier 节点销售活动&#xff0c;引领一场ZK计算革命。 长期以来&#xff0c;加密市场以其独特的波动性和增长潜力&#xff0c;持续吸引着全球投资者的目光。而历史数据表明&#xff0c;市场往往在一年…

数据结构与算法笔记:基础篇 - 分治算法:谈一谈大规模计算框架MapReduce中的分治思想

概述 MapReduce 是 Google 大数据处理的三姐马车之一&#xff0c;另外两个事 GFS 和 Bigtable。它在倒排索引、PageRank 计算、网页分析等搜索引擎相关的技术中都有大量的应用。 尽管开发一个 MapReduce 看起来很高深。实际上&#xff0c;万变不离其宗&#xff0c;它的本质就…

three.js 基础01

目录 1.场景创建 Scene() 2.常用形状集几何体「Geometry」[可设置长宽高等内容&#xff0c;如&#xff1a;new THREE.BoxGeometry(...)] 3.常用材质「Material」[可设置颜色等内容&#xff0c;如&#xff1a;new THREE.MeshBasicMaterial({})] 4.添加、定位 5.相机api 6…