Spring MVC学习随笔-文件下载和上传(配置文件上传解析器multipartResolver)

news2025/1/14 0:47:31

学习视频:孙哥说SpringMVC:结合Thymeleaf,重塑你的MVC世界!|前所未有的Web开发探索之旅
学习视频:【编程不良人】继spring之后快速入门springmvc,面对SpringMVC不用慌

六、SpringMVC 文件上传下载

6.1 文件上传

  1. 定义

    指的是用户将自己本地计算机中文件通过网络上传到系统所在服务器上的过程称为文件上传。

  2. 需要用户提交文件时,必须开发文件上传功能

  3. SpringMVC中如何开发文件上传

    1. 在系统中开发一个文件上传页面,包含一个form表单,表单中开发一个本地计算机文件入口

    2. form表单 **method提交方式必须是post,**添加属性:enctype = application/x-www-form-urlencoded(文本) | multipart/form-data

    3. 在SpringMVC配置文件加入文件上传解析器配置

      注意:文件上传解析器必须存在id,且id必须为multipartResolver

    4. 引入文件上传的相关依赖

      commons-fileupload

  • 编码

    distpacher.xml 进行文件上传解析器的配置
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
    
    // 引入相关依赖
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>
    
    **// 传递的数据name属性名必须和控制器接受的形参名一致**
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>upload</title>
    </head>
    <body>
        <h1>文件上传</h1>
        <form action="${pageContext.request.contextPath}/file/upload" method="post" enctype="multipart/form-data">
            <input type="file" name="**img**"/>
            <input type="submit" value="上传文件"/>
        </form>
    </body>
    </html>
    

    在服务器上放置文件夹接受上传文件的步骤:在webapp下面创建一个文件夹(不能是空文件夹) ⇒ maven执行clean ⇒ 重启服务器,target下会自动创建此文件夹

    **控制层 通过MultipartFile形参接受页面传过来的文件,形参名必须与数据名(name属性)一致**
    @Controller
    @RequestMapping("file")
    public class FileController {
    
        @RequestMapping("upload")
        public String upload(MultipartFile **img**, HttpServletRequest request) throws IOException {
            System.out.println("文件名" + img.getOriginalFilename());
            System.out.println("文件大小" + img.getSize());
            System.out.println("文件类型" + img.getContentType());
            // 文件上传
            // 1. 根据upload相对路径部署到服务之后的绝对路径 target/..../upload
            String realPath = request.getSession().getServletContext().getRealPath("/upload");
            // 2.将文件上传到upload对应路径
            img.transferTo(new File(realPath,img.getOriginalFilename()));
            return "index";
        }
    }
    
  • 文件上传细节处理

    1. 如何修改文件上传的原始名称

      使用文件的原始名称做为上传文件的最终名称,会导致文件覆盖。所以每次用户上传文件需要修改一个新的名称。

      		// 重命名:获取后缀,随机命名  substring | 工具类 commons
              String fileName = img.getOriginalFilename();
      //        int i = fileName.lastIndexOf(".");
      //        String name = fileName.substring(i);
              String extension = FilenameUtils.getExtension(fileName);
              String newFileName = UUID.randomUUID().toString().replace("-","")+"."+extension;
              // 2.将文件上传到upload对应路径
              img.transferTo(new File(realPath,newFileName));
      
    2. 对上传的文件进行管理,将用户每天上传的文件放入当天日期目录中?

      // 3. 生成当天日期目录
      LocalDate now = LocalDate.now();
      File dateDir = new File(realPath, now.toString());
      if (!dateDir.exists()) {
          dateDir.mkdirs();
      }
      // 4.将文件上传到upload对应路径
      **img.transferTo(new File(dateDir,newFileName));
      
    3. SpringMVC中如何解决文件上传的大小限制

      注意:在SpringMVC中默认上传没有大小限制,所以需要限制用户上传文件的大小限制

6.2 文件下载

  1. 定义

    用户将服务器文件下载到本地计算机的过程称为文件下载

  2. 开发文件下载

    1. 确定系统中哪些文件需要用户下载
    2. 将需要下载的文件放入指定下载目录中
    3. 开发一个页面提供文件下载链接
    4. 开发下载Controller
  • 编码

    <body>
        <h1>文件下载</h1>
        <a href="${pageContext.request.contextPath}/file/download?fileName=aa.txt">aa.txt</a>
    </body>
    
    /* 处理文件下载*/
    @RequestMapping("download")
    public void download(String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("下载文件的名称 = " + fileName);
        // 1. 根据下载相对目录获取下载目录在服务器部署之后的绝对目录
        String realPath = request.getSession().getServletContext().getRealPath("/down");
        // 2.通过文件输入流读取文件
        FileInputStream is = new FileInputStream(new File(realPath, fileName));
        // 3.获取响应输出流
        response.setContentType("text/plain;charset=UTF-8");
        ServletOutputStream os = response.getOutputStream();
        // 4.附件下载文件  attachment(附件)  inline(在线打开)
        response.setHeader("content-disposition", "attachment;fileName=" + fileName);
        // 5.处理下载流复制
        // aa.txt
        int len;
        byte[] b = new byte[1024];
        while (true) {
            len = is.read(b);
            if (len == -1) {
                break;
            }
            os.write(b, 0, len);
        }
        is.close();
        os.close();
    }
    

6.3 文件下载细节处理

  • 实现在线打开下载+附件下载的功能(如下图)

  • 编码

    **// 通过url传递的数据控制参数变为inline或attachment**
    /* 处理文件下载*/
        @RequestMapping("download")
        public void download(String **openStyle**, String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
    				**openStyle=openStyle==null?"inline":"attachment";**
            System.out.println("下载文件的名称 = " + fileName);
            // 1. 根据下载相对目录获取下载目录在服务器部署之后的绝对目录
            String realPath = request.getSession().getServletContext().getRealPath("/down");
            // 2.通过文件输入流读取文件
            FileInputStream is = new FileInputStream(new File(realPath, fileName));
            // 3.获取响应输出流
            response.setContentType("text/plain;charset=UTF-8");
            ServletOutputStream os = response.getOutputStream();
            // 4.附件下载文件  attachment(附件)  inline(在线打开)
            response.setHeader("content-disposition", **openStyle**+";fileName=" + fileName);
            // 5.处理下载流复制
            // 传统写法 aa.txt
    //        int len;
    //        byte[] b = new byte[1024];
    //        while (true) {
    //            len = is.read(b);
    //            if (len == -1) {
    //                break;
    //            }
    //            os.write(b, 0, len);
    //        }
    //        is.close();
    //        os.close();
            // 代替上面传统写法,commons包提供了io流更方便  操作io流使用IOUtils  操作file 用 FileUtils
            **IOUtils.copy(is, os);// 输入流拷贝到输出流
            IOUtils.closeQuietly(is);// 优雅关闭 安静关流
            IOUtils.closeQuietly(os);// 优雅关闭 安静关流**
    
        }
    
    <h1>文件下载</h1>
    <ul>
        <li>
            aa.txt
            <a href="${pageContext.request.contextPath}/file/download?fileName=aa.txt">在线打开</a>
            <a href="${pageContext.request.contextPath}/file/download?fileName=aa.txt&openStyle=attachment">附件下载</a>
        </li>
        <li>
            springmvc.png
            <a href="${pageContext.request.contextPath}/file/download?fileName=springmvc.png">在线打开</a>
            <a href="${pageContext.request.contextPath}/file/download?fileName=springmvc.png&openStyle=attachment">附件下载</a>
        </li>
        <li>
            自我介绍.txt
            <a href="${pageContext.request.contextPath}/file/download?fileName=自我介绍.txt">在线打开</a>
            <a href="${pageContext.request.contextPath}/file/download?fileName=自我介绍.txt&openStyle=attachment">附件下载</a>
        </li>
    </ul>
    
  • 解决文件名为中文时,下载后文件名变为乱码的问题

    // 对fileName编码,转为UTF-8
    response.setHeader("content-disposition", openStyle+";fileName=" + **URLEncoder.encode(fileName,"UTF-8")**);
    

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

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

相关文章

【算法】单调队列 滑动窗口最大值

文章目录 例题——239. 滑动窗口最大值相关练习1438. 绝对差不超过限制的最长连续子数组解法1——两个单调队列分别维护最大值和最小值解法2——有序集合TreeMap 2398. 预算内的最多机器人数目解法1——二分答案 单调队列解法2——双指针 单调队列 &#xff08;不固定大小的滑…

使用docker切换任意版本cuda使用GPU

1.现存问题 在主机上运行很多下载来的机器学习代码时&#xff0c;这些大都运行在不同版本的tensorflow-gpu或者pytorch等的包下的。但是&#xff0c;运行代码的过程中&#xff0c;存在匹配的问题&#xff1a; 1.不同的版本的tensorflow-gpu或pytorch对cuda版本的适配也不一样…

Day49力扣打卡

打卡记录 需要添加的硬币的最小数量&#xff08;归纳法&#xff09; 链接 按着已经加入的数&#xff0c;以此偏移对应距离&#xff0c;从而得到新的连续数&#xff0c;若是出现断层则计入最小次数中&#xff0c;再以此偏移对应距离。 class Solution:def minimumAddedCoins(s…

H3C交换机堆叠配置(四台交换机配置堆叠)

最近需要扩大公司新项目环境&#xff0c;新买够了&#xff0c;四台二层交换机和两台三层交换机&#xff0c;二层交换机型号为H3C S5120&#xff0c;三层交换机为H3C S5500&#xff0c;因为项目有关于国家项目&#xff0c;必须使用国产网络设备&#xff0c;现在需要对四台交换机…

Python---函数递归---练习:使用递归求N的阶乘(如n=100)(本文以递归算法 解法为主)

相关链接&#xff1a;Python---函数递归---练习&#xff1a;斐波那契数列&#xff08;本文以递归算法为主&#xff09;-CSDN博客 Python---if选择判断结构、嵌套结构&#xff08;if elif else&#xff09;_python多重if嵌套-CSDN博客 案例&#xff1a;使用递归求N的阶乘&…

基于springboot + vue体育馆使用预约平台

qq&#xff08;2829419543&#xff09;获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;采用vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xf…

Google Earth Engine谷歌地球引擎计算多年中某两个时间点之间遥感数据差值的平均值

本文介绍在谷歌地球引擎GEE中&#xff0c;提取、计算某一种遥感影像产品在连续的多年中&#xff0c;2个不同时相的数据差值的多年平均值&#xff0c;并将计算得到的这一景差值的结果图像导出的方法。 本文是谷歌地球引擎&#xff08;Google Earth Engine&#xff0c;GEE&#x…

机器学习-回归问题(Regression)

前言 与KNN分类任务预测的输出为离散型不同. 在机器学习中&#xff0c;回归任务是用于预测连续数值型变量的任务。回归任务在很多领域都有着广泛的应用. 回归问题求解 在一个回归问题中&#xff0c;很显然模型选择和好坏会直接关系到将来预测结果的接近程度&#xff0c;举个…

RPG项目01_新输入输出

基于“RPG项目01_脚本代码”&#xff0c;本次修改unity的新输入输出系统。本次修改unity需要重启&#xff0c;如果一直跟着做教学项目&#xff0c;请先保存项目&#xff0c;再继续修改unity为新输入输出系统。 向下翻&#xff0c; 向下翻&#xff0c; 选择both加入新输入输出系…

疫苗接种(链表练习)

很明显&#xff0c;数组也可以做&#xff0c;但是我想练习链表 这道题我上交的时候&#xff0c;同一份代码&#xff0c;三个编译器&#xff0c;三个成绩&#xff0c;有点搞心态 代码如下&#xff1a; #include<stdio.h> #include<math.h> #include<stdlib.h&…

html动漫网页设计分享 紫罗兰永恒花园网页作业成品带视频,注册登录,表格,表单

html5静态网页设计要是用HTML DIVCSS JS等来完成页面的排版设计,一般的网页作业需要融入以下知识点&#xff1a;div布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点&#xff0c;学生网页作业源码可以…

重新认识Word——样式

重新认识Word Word样式给所有一级标题加上一级标题样式修改标题一样式&#xff0c;符合要求 正文样式标题前的小黑点导航窗格样式的相互复制Word一键转PPT 话说回来&#xff0c;一个程序员平时可能还看不起office全家桶的软件&#xff0c;但是&#xff0c;在实际的生活运用中&a…

Elk-filebeat

前言 Elk&#xff1a;filebeat搜集日志工具和logstash相同 Filebeat是一个轻量级的日志收集工具&#xff0c;所使用的资源比logstash部署和启动时使用的资源更小 Filebeat可以运行在非Java环境&#xff0c;他可以代理logstash在非Java环境上收集日志 Filebeat无法实现数据的…

设计基于STM32的温度传感器实时数据采集和显示系统

温度传感器作为常见的传感器之一&#xff0c;被广泛应用于各种领域&#xff0c;如工业自动化、家电控制等。为了实时监测和控制温度&#xff0c;设计一个基于STM32的温度传感器实时数据采集和显示系统是很有必要的。本文将详细介绍如何设计这样一个系统&#xff0c;并提供相应的…

[蓝桥杯 2020 省 AB1] 解码

做题前思路&#xff1a; 1.因为是多组输入&#xff0c;又包含字符于是我们可以先定义一个char类型数组arr 2.定义数组的长度&#xff1a;题目说简写&#xff08;字母加数字&#xff09;长度不超过100&#xff0c;但原来的长度可能超过100&#xff0c;加上小明不会将连续超过9…

英飞凌(Infineon)TC397链接文件解析

本篇文章首先介绍了链接文件在整个代码编译过程中所起到的作用&#xff0c;然后根据TC397芯片对应的链接文件涉及的链接命令&#xff0c;参照官网的示例给出了常见的使用方法&#xff0c;最后分为MEMORY与SECTIONS两个部分以脚本命令走读的形式解析了TC397芯片的链接文件&#…

5_企业架构LNMP高可用负载均衡服务器

企业架构LNMP高可用负载均衡服务器之Nginx 学习目标和内容 1、能够描述负载均衡的作用 2、能够了解负载均衡常见实现方式 3、能够使用Nginx实现负载均衡 4、能够描述Nginx的常见负载均衡算法 一、背景描述及其方案设计 1、业务背景描述 时间&#xff1a;2011.6.-2013.9 发布产…

谈一谈内存对齐

文章目录 一&#xff0c;什么是内存对齐&#xff1f;二&#xff0c;为什么要有内存对齐&#xff1f;三&#xff0c;内存对齐规则&#xff1f; 一&#xff0c;什么是内存对齐&#xff1f; 现代计算机中的内存空间都是按字节划分的&#xff0c;理论上似乎我们对任何类型变量的访…

【iOS控件】—— UIPickerView的使用

【iOS控件】—— UIPickerView的使用 一. 简述UIPickerView1. 什么是UIPickerView2. UIPickerView遵守的协议 二. 测试Demo三. 总结 一. 简述UIPickerView 先看一下UIPickerView的效果图&#xff1a; 1. 什么是UIPickerView UIPickerView是iOS平台上的一个用户界面元素&am…

力扣 --- 最长公共前缀

题目描述&#xff1a; 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1&#xff1a; 输入&#xff1a;strs ["flower","flow","flight"] 输出&#xff1a;"fl"…