【SpringMVC】SpringMVC实现文件上传

news2025/1/22 19:53:00

1.一般的文件上传

1.1 文件上传的必要前提

  • form 表单的 enctype 取值必须是:multipart/form-data(默认值是:application/x-www-form-urlencoded)

    enctype:是表单请求正文的类型

  • method 属性取值必须是 Post

  • 提供一个文件选择域<input type="file" />

1.2 文件上传的原理分析

当 form 表单的 enctype 取值不是默认值后,request.getParameter()将失效。

当enctype=”application/x-www-form-urlencoded”时,form 表单的正文内容是:key=value&key=value&key=value

当enctype 取值为 Mutilpart/form-data 时,请求正文内容就变成:每一部分都是 MIME 类型描述的正文

-----------------------------7de1a433602ac 			分界符
Content-Disposition: form-data; name="userName" 	协议头
aaa 											协议的正文
-----------------------------7de1a433602ac
Content-Disposition: form-data; name="file";
filename="C:\Users\krislin\Desktop\fileupload_demofile\b.txt"
Content-Type: text/plain 						协议的类型(MIME 类型)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-----------------------------7de1a433602ac--

1.3 借助第三方组件实现文件上传

使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:Commons-fileupload 和commons-io。commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它工作时需要 commons-io 包的支持。

2.SpringMVC传统方式的文件上传

传统方式的文件上传,指的是我们上传的文件和访问的应用存在于同一台服务器上。并且上传完成之后,浏览器可能跳转。

2.1 实现步骤

1.添加maven依赖

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

2.编写jsp页面

<form action="/fileUpload" method="post" enctype="multipart/form-data">
    名称:<input type="text" name="picname"/><br/>
    图片:<input type="file" name="uploadFile"/><br/>
    <input type="submit" value=" 上传 "/>
</form>

3.编写控制器

/**
* 文件上传的的控制器
*/
@Controller("fileUploadController")
public class FileUploadController {
    /**
    * 文件上传
    */
    @RequestMapping("/fileUpload")
    public String testResponseJson(String picname,MultipartFile uploadFile,HttpServletRequest request) throws Exception{
        //定义文件名
        String fileName = "";
        //1.获取原始文件名
        String uploadFileName = uploadFile.getOriginalFilename();
        //2.截取文件扩展名
        String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1,uploadFileName.length());
        //3.把文件加上随机数,防止文件重复
        String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
        //4.判断是否输入了文件名
        if(!StringUtils.isEmpty(picname)) {
        	fileName = uuid+"_"+picname+"."+extendName;
        }else {
        	fileName = uuid+"_"+uploadFileName;
        }
        System.out.println(fileName);
        //2.获取文件路径
        ServletContext context = request.getServletContext();
        String basePath = context.getRealPath("/uploads");
        //3.解决同一文件夹中文件过多问题
        String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        //4.判断路径是否存在
        File file = new File(basePath+"/"+datePath);
        if(!file.exists()) {
        	file.mkdirs();
        }
        //5.使用 MulitpartFile 接口中方法,把上传的文件写到指定位置
        uploadFile.transferTo(new File(file,fileName));
        return "success";
        }
}

4.配置文件解析器

<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" <!-- id 的值是固定的-->
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置上传文件的最大尺寸为 5MB -->
    <property name="maxUploadSize">
    	<value>5242880</value>
    </property>
</bean>

注意:
文件上传的解析器 id 是固定的,不能起别的名称,否则无法实现请求参数的绑定。(不光是文件,其他
字段也将无法绑定)

3.SpringMVC跨服务器方式的文件上传

3.1 分服务器的目的

在实际开发中,我们会有很多处理不同功能的服务器。例如:
应用服务器:负责部署我们的应用
数据库服务器:运行我们的数据库
缓存和消息服务器:负责处理大并发访问的缓存和消息
文件服务器:负责存储用户上传文件的服务器。
(注意:此处说的不是服务器集群)

分服务器处理的目的是让服务器各司其职,从而提高我们项目 的运行效率。

3.2 准备个 两个 tomcat 服务器的 ,并创建一个用于存放图片的 web 工程

在文件服务器的 tomcat 配置中加入,允许读写操作。文件位置:

加入内容:

加入此行的含义是:接收文件的目标服务器可以支持写入操作。

3.3 添加maven依赖

在我们负责处理文件上传的项目中添加文件上传的必备maven依赖

    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.6</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.sun.jersey/jersey-client -->
    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-client</artifactId>
      <version>1.19.4</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.sun.jersey/jersey-core -->
    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-core</artifactId>
      <version>1.19.4</version>
    </dependency>

3.4 编写控制器实现上传图片

/**
* 响应 json 数据的控制器
*/
@Controller("fileController")
public class FileController {
	public static final String FILESERVERURL ="http://localhost:9090/day06_spring_image/uploads/";
    /**
    * 文件上传,保存文件到不同服务器
    */
    @RequestMapping("/fileUpload2")
    public String testResponseJson(String picname,MultipartFile uploadFile) throws Exception{
        //定义文件名
        String fileName = "";
        //1.获取原始文件名
        String uploadFileName = uploadFile.getOriginalFilename();
        //2.截取文件扩展名
        String extendName =
        uploadFileName.substring(uploadFileName.lastIndexOf(".")+1,
        uploadFileName.length());
        //3.把文件加上随机数,防止文件重复
        String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
        //4.判断是否输入了文件名
        if(!StringUtils.isEmpty(picname)) {
        fileName = uuid+"_"+picname+"."+extendName;
        }else {
        fileName = uuid+"_"+uploadFileName;
        }
        System.out.println(fileName);
        //5.创建 sun 公司提供的 jersey 包中的 Client 对象
        Client client = Client.create();
        //6.指定上传文件的地址,该地址是 web 路径
        WebResource resource = client.resource(FILESERVERURL+fileName);
        //7.实现上传
        String result = resource.put(String.class,uploadFile.getBytes());
        System.out.println(result);
        return "success";
    }
}

3.5 编写jsp页面

<h2>文件上传-不同服务器之间</h2>
<form action="${pageContext.request.contextPath}/fileUpload2" method="post" enctype="multipart/form-data">
    名称: <input type="text" name="picname"><br/>
    图片: <input type="file" name="uploadFile"><br/>
    <input type="submit" value="上传">
</form>

3.6 配置解析器

<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置上传文件的最大尺寸为 5MB -->
    <property name="maxUploadSize">
        <value>5242880</value>
    </property>
</bean>

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

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

相关文章

代码随想录二刷day2

代码随想录复习 文章目录代码随想录复习209.长度最小的子数组&#xff08;滑动窗口&#xff09;76.最小覆盖子串904.水果成篮59.螺旋矩阵2螺旋矩阵1209.长度最小的子数组&#xff08;滑动窗口&#xff09; 209.长度最小的子数组 复习一下滑动窗口&#xff0c;滑窗的复杂度还是…

MySQL时间查询讲解+实战教学(查询本月、上个月、下个月等等的数据)

MySql时间查询 MySql查询当前时间 查询 年-月-日 时:分:秒 select now() 查询 年-月-日 select DATE(CURDATE()) 查询 年-月 select date_format(NOW(),%Y-%m) 查询当前年 select YEAR(CURDATE()) 查询当前月 select MONTH(CURDATE()) 查询当前日 select DAYOFMONTH(NOW()) 查…

【论文简述】Efficient Multi-view Stereo by Iterative Dynamic Cost Volume(CVPR 2022)

一、论文简述 1. 第一作者&#xff1a;Shaoqian Wang、Bo Li 2. 发表年份&#xff1a;2022 3. 发表期刊&#xff1a;CVPR 4. 关键词&#xff1a;MVS、深度学习、动态代价体、GRU、迭代优化 5. 探索动机&#xff1a;由于正则化步骤需要较多的GPU内存和处理时间&#xff0c…

大话JMeter4|不同的并发数可以自动化做压测吗?

1080709 23.5 KB 上节课爱画漫画的小哥哥用漫画形式向大家展示了JMeter的进阶用法&#xff1a;如何搭建InfluxDB&#xff0c;使用更炫酷的Grafana。 看到很多小伙伴觉得看的不过瘾&#xff0c;在强烈的催促下&#xff0c;小哥哥的新文章又出来了。这次小哥哥又给我们带来怎样的…

vue + nodejs + npm

node.js下载 1、如图所示&#xff1a; 2、建立node_cache、node_global文件夹&#xff1a; 然后运行以下2条命令 npm config set prefix “D:\node-v14.15.0-win-x64\node_global” npm config set cache “D:\node-v14.15.0-win-x64\node_cache” 执行npm list -global查看&…

编译原理——求短语、直接短语(简单短语)、素短语、句柄

先介绍一下短语、直接短语&#xff08;简单短语&#xff09;、素短语、句柄怎么求&#xff1a;这个图是核心 然后通过一些例题&#xff0c;实战一下&#xff1b; 根据上面介绍的概念、求法&#xff0c;应用一下即可&#xff1b; 例题1 短语&#xff1a;注意对于每一个子树&a…

数字孪生技术助力高炉数字化建设的可行性

随着数字孪生等新一代信息技术的快速发展&#xff0c;数字化转型已成为企业重塑竞争优势的关键举措。依托数字孪生技术&#xff0c;对炼铁高炉进行物联网、数字化信息系统建设&#xff0c;实现了高炉运行状态的数字化监测与预警&#xff0c;数字孪生系统凭借在数字化、模型化、…

利用WordPress搭建属于自己的网站

怎么用WordPress给自己搭建了一个网站&#xff1f;可能很多人都想拥有属于自己的网站&#xff0c;这篇文章就找你怎么利用WordPress搭建属于自己的网站。如果你也正好有搭建个人网站的想法&#xff0c;那么本文会给你一个参考&#xff0c;我尽量写的比较详细&#xff0c;给自己…

【Ctfer训练计划】——(五)

作者名&#xff1a;Demo不是emo 主页面链接&#xff1a;主页传送门创作初心&#xff1a;舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座右…

Java on VS Code 11月更新|VS Code Java 开发者超200万!

作者&#xff1a;Nick Zhu - Senior Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;我们很高兴与大家分享一个好消息&#xff0c;现在 Visual Studio Code 上已有超过 200 万 Java 开发者&#xff0c;这离不开长期以来社区以…

JavaSE笔记——异常、断言

文章目录前言一、处 理 错 误1.异常分类2.声明受查异常3.如何抛出异常4.创建异常类二、捕获异常1.捕获异常2.捕获多个异常3.再次抛出异常与异常链4.finally 子句5.带资源的 try 语句三、使用断言1.断言的概念2.启用和禁用断言3.使用断言完成参数检查总结前言 在现实世界中却充…

由浅入深学安全-1

由浅入深学安全 常用术语解析 肉鸡 肉鸡也称傀儡机&#xff0c;是指可以被黑客远程控制的机器。 比如用灰鸽子等诱导客户点击或者电脑被黑客攻破或用户电脑有漏洞被种植了木马&#xff0c;黑客可以随意操纵它并利用它做任何事情。 一句话木马 一句话木马主要用来配合菜刀…

【Java系列】还在为Java运算符而烦恼吗?一篇文章带你解答心中烦恼

返回主篇章         &#x1f447; 【Java】才疏学浅小石Java问道之路 Java基本运算符1. 算数运算符分类运算法则2. 关系运算符分类注意项3. 逻辑运算符分类运算法则4. 短路逻辑运算符分类运算法则5. 赋值运算符拓展6. 三元运算符格式运算法则7. 自增自减运算符分类使用…

12-Golang中的嵌套分支以及switch语句的用法

Golang中的嵌套分支以及switch语句的用法嵌套分支基本介绍基本语法switch基本介绍基本语法流程图使用细节嵌套分支 基本介绍 在一个分支结构中又完整的嵌套了另一个完整的分支结构&#xff0c;里面的分支的结构称为内层分支外面的分支结构称为外层分支 基本语法 if 条件表达…

声明式服务调用OpenFeign

文章目录一. OpenFeign1. Feign 与 OpenFeign二. OpenFeign的使用三. OpenFeign自定义配置1. 修改日志级别2. 超时控制四. OpenFeign性能优化五. OpenFeign最佳实践1. 继承2. 抽取PS: 本文为作者学习笔记&#xff0c;实际技术参加意义不大&#xff0c;本文将持续改进完善。 一…

Doris(二)

目录1、Doris数据的导入和导出1.1 数据导入1.1.1 Broker Load1.1.1.1 适用场景1.1.1.2 基本原理1.1.1.3 基本语法1.1.1.4 导入示例1.1.1.5 查看导入1.1.1.6 取消导入1.1.2 Stream Load1.1.2.1 适用场景1.1.2.2 基本原理1.1.2.3 基本语法1.1.2.4 导入示例1.1.2.5 取消导入1.1.3 …

蓝牙耳机什么牌子好?性价比最高的蓝牙耳机排行榜

近年来&#xff0c;蓝牙耳机品牌与日俱增&#xff0c;可供人们选择的范围也越来越大。当然&#xff0c;主打性价比的蓝牙耳机品牌也有很多&#xff0c;下面&#xff0c;我来给大家分享几款性价比最高的蓝牙耳机&#xff0c;一起来看看吧。 一、南卡小音舱蓝牙耳机 售价&#…

寒潮来袭,这款产品在跨境电商市场卖脱销

年底的寒潮来袭&#xff0c;全球市场热销产品分析跨境电商在年底冬季属于销售旺季&#xff0c;大多数的跨境电商卖家们都开始尽情努力&#xff0c;争取今年获得大批收入&#xff0c;在这个年底既是旺季也是困难季。2022年底旺季时分&#xff0c;有不少产品在跨境电商市场卖脱销…

jQuery index()

jQuery index() 概述 在jQuery中&#xff0c;我们可以使用index()方法来获取当前jQuery对象集合中“指定元素”的索引值。 语法 $(元素).index()说明 index()方法可以接受一个“jQuery对象”或“DOM对象”作为参数&#xff0c;不过一般情况下&#xff0c;我们很少会使用到…

Idea常用快捷键(MacOS和Win平台)持续更新ing~

小名在刚换MacOS系统时总结的一些Idea快捷键&#xff0c;这里小名把Win的对比快捷键和功能都列出来&#xff0c;方便像小名这样“肌肉记忆”的小伙伴顺利过渡&#xff5e; 当然&#xff0c;这些都是小名平日工作常用的快捷键&#xff0c;不熟悉这些快捷键的Win平台小伙伴也可以…