Spring MVC 文件上传和下载

文章目录

  • Spring MVC 中文件上传
    • 利用 commons-fileupload 文件上传
    • 使用 Servlet 3.1 内置的文件上传功能
  • Spring MVC 中文件下载

Spring MVC 中文件上传

为了能上传文件,必须将 from 表单的 method 设置为 POST,并将 enctype 设置为 multipart/form-data

实现文件上传的 “底层” 方案有 2 种:

  • 使用 Apache Commons FileUpload 包

  • 使用 Servlet 3.1 内置的文件上传功能

无论你的底层是使用上述的哪种方案,Spring MVC 都对它们作出了『包装』,让 Spring MVC 中的上传文件的代码简化而统一:提供一个 MultipartResolver,并将 <input type=“file” …> 类型的请求参数绑定到请求处理方法的 MultipartFile 类型的参数上。(两者具体的类型有所不同)

这需要提前说明以下,Spring MVC 利用 Servlet 3.1 内置的文件上传功能上传文件时,有个小问题。有人发现无法将它所用到的 StandardMultipartResolver 的编码从默认的 iso-8859-1 改为 UTF-8 。也有人分析,在使用 tomcat 7 时会出现这个问题,并认为这是 tomcat 7 的 bug 。所有,简单起见,建议优先考虑 commons-fileupload 方案。

具体讨论可参见:stakoverflow 。

利用 commons-fileupload 文件上传

利用 commons-fileupload 文件上传需要利用引入 commons-fileupload(它依赖于 commons-io 包)

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

Spring MVC 是通过 MultipartResolver 的 JavaBean 提供、支持文件上传功能。commons-fileupload 中该接口的实现类是 CommonsMultipartResolver

简单来说,CommonsMultipartResolver 是 Spring MVC 去利用 commons-fileupload 实现上传功能的『桥梁』。

spring-web.xml 中添加如下配置,让 Spring 负责创建并初始化该 Bean 。

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="104857600" /><property name="maxInMemorySize" value="4096" /><property name="defaultEncoding" value="UTF-8"/><!-- 更多配置根据具体需求进一步再学习/使用 -->
</bean>

至此,配置结束。在 Spring MVC 的 Controller 中,Spring MVC 就可以将用户上传的数据绑定到 CommonsMultipartFile 类型的参数上。

注意
此处的 @RequestParam() 不能省略,即便是 name 与 name 一致。

@RequestMapping("/upload.do")
public String upload(String username, String password,@RequestParam("uploadfile") CommonsMultipartFile uploadfile) throws IOException {log.info("{}", uploadfile.getName());log.info("{}", uploadfile.getOriginalFilename());String path = "D:/" + new Date().getTime() + uploadfile.getOriginalFilename();uploadfile.transferTo(new File(path));return "";
}

CommonsMultipartFile 支持如下功能:

方法说明
byte[] getBytes()以字节数组的形式返回文件的内容
String getContentType()返回文件的内容类型
InputStream getInputStream()返回一个 InputStream,可以从中去读文件内容
String getName()返回请求参数的 name
String getOriginalFilename()返回文件原本的文件名
long getSize()返回文件大小(单位字节)
boolean isEmpty()判断上传的文件是否为空
void transferTo(File destination)将上传的文件保存到指定位置

如果从页面上同时上传多个文件,那么页面上的 file 可以使用同一个 name,而代码中则使用 CommonsMultipartFile 的数组类型的参数接受。数组中的每一个 MultipartFile 就代表着一个上传的文件。

<p><input type="file" name="files"></p>
<p><input type="file" name="files"></p>
<p><input type="file" name="files"></p>
@RequestParam("files") CommonsMultipartFile[] files

使用 Servlet 3.1 内置的文件上传功能

补充,其实 Servlet 3.0 就已经开始提供内置的上传功能,只不过该功能在 Servlet 3.1 中进一步增强/改进/完成。因此一般的说法是 Servlet 3.1 支持内置的文件上传功能。

利用 Servlet 3.1 实现文件上传的概念和使用过程和利用 commons-fileupload 本质上并无太大区别。只不过有几处小区别:

  1. 提供文件上传功能的是 StandardServletMultipartResolver ,不再是 CommonsMultipartResolver

spring-web.xml:

<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>
  1. 对上传过程中的相关配置,是配置在 web.xml 中的 DispacherServlet 下,而非 spring-web.xml 中的 MultipartResolver 下。

web.xml:

<servlet><servlet-name>hello</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param>...</init-param><load-on-startup>...</load-on-startup><multipart-config><location>d:/</location> <!-- 临时文件的目录。该目录必须存在 --><max-file-size>2097152</max-file-size> <!-- 一次请求上传的单个文件最大2M --><max-request-size>4194304</max-request-size> <!-- 一次请求上传的多个文件整体大小不超过4M --></multipart-config>
</servlet>
  1. Controller 代码中使用的注解是 @RequestPart(“file”),而非 @RequestParam;绑定的参数类型是 MultipartFile,而不是 CommonsMultipartFile 。
@RequestMapping("/upload.do")
public String upload(String username, String password,@RequestPart("files") MultipartFile[] files) 

MultipartFile 对象的功能与 CommonsMultipartFile 基本类似。

Spring MVC 中文件下载

Spring MVC 提供了一个 ResponseEntity 类型,使用它可以很方便地定义返回 HttpHeadersHttpStatus ,以实现下载功能。

@RequestMapping("/download")
public ResponseEntity<byte[]> download(HttpServletRequest req,@RequestParam("filename") String filename, Model model) throws Exception {// 1. 准备一个字节数组(字节数组的内容来源于一个文件)。//    这个字节数组,就是在本次 HTTP 请求中 Tomcat 要回给客户端浏览器的内容、数据。String path = req.getServletContext().getRealPath("upload");File file = new File(path + File.separator + filename);byte[] bytes = FileUtils.readFileToByteArray(file);// 2. 创建一个 ResponseEntity 对象。它代表着一个 HTTP 响应。//    而一个 HTTP 响应又有行-头-体。其中『体』里存放的就是上述的代表文件内容的字节数组HttpHeaders headers = new HttpHeaders();// 解决文件名乱码问题// String downloadFileName = new String(filename.getBytes("UTF-8"), "iso-8859-1");// 第一个放在 header 中的键值对 attachment=xxxheaders.setContentDispositionFormData("attachment", filename);// 第二个放在 header 中的键值对 media-type=xxxxheaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes,          // 响应体中携带的数据headers,        // 响应头HttpStatus.OK); // 响应行中的状态码return responseEntity;
}

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

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

相关文章

阿里云服务器怎么购买价格更便宜?优惠大揭秘!

阿里云服务器租用价格表2024年最新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核…

cesium 平滑显示billboard 透明度

描述&#xff1a;加载billboard的时候&#xff0c;要么是显示&#xff0c;要么是隐藏&#xff0c;不能平滑的显示&#xff0c;有个从不显示到显示的过程 解决方案&#xff1a;创建billboard的时候给一个color&#xff0c;颜色为(255,255,255)&#xff0c;透明度从0-1 let opaci…

C#:循环中断

任务描述 实现九九乘法表&#xff0c;按照编程要求&#xff0c;使用break跳出循环 测试说明 测试过程&#xff1a; 平台将编译用户补全代码&#xff0c;并根据程序的输出判断程序是否正确。 以下是测试样例&#xff1a; 测试输入&#xff1a; 预期输出&#xff1a; we found…

A Learning-Based Approach for IP Geolocation(2010年)

下载地址:Towards IP geolocation using delay and topology measurements | Proceedings of the 6th ACM SIGCOMM conference on Internet measurement 被引次数:185 Eriksson B, Barford P, Sommers J, et al. A learning-based approach for IP geolocation[C]//Passive …

【UE Niagara】自定义模块的简单使用

效果 步骤 新建一个Niagara系统&#xff0c;使用“Empty”模板&#xff0c;这里命名为“NS_Custom” 打开“NS_Custom”&#xff0c;添加一个“Spawn Burst Instantaneous”来单次生成1个粒子 在“Emitter State”模块中&#xff0c;设置生命循环模式为“Self”&#xff0c;循…

【洛谷 B3611】【模板】传递闭包 题解(有向图+邻接矩阵+Floyd算法+传递闭包+位运算)

【模板】传递闭包 题目描述 给定一张点数为 n n n 的有向图的邻接矩阵&#xff0c;图中不包含自环&#xff0c;求该有向图的传递闭包。 一张图的邻接矩阵定义为一个 n n n\times n nn 的矩阵 A ( a i j ) n n A(a_{ij})_{n\times n} A(aij​)nn​&#xff0c;其中 a i…

【vue】toRef,toRefs

toRef&#xff1a;把一个 响应式对象 转换为对应的ref变量toRefs&#xff1a;把一个 响应式对象 转换为对应的ref对象 代码 <template><P>mname: {{ mname }} </P><P>mage: {{ mage }} </P><P>msex: {{ msex }} </P><P>mhobb…

代码随想录算法训练营第三十九天| 62.不同路径、63. 不同路径 II

62.63 题目&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。问总共有多少条不同的路…

购物车实现

目录 1.购物车常见的实现方式 2.购物车数据结构介绍 3.实例分析 1.controller层 2.service层 1.购物车常见的实现方式 方式一&#xff1a;存储到数据库 性能存在瓶颈方式二&#xff1a;前端本地存储 localstorage在浏览器中存储 key/value 对&#xff0c;没有过期时间。s…

程序员为啥不自己单干?想过,但是

偶尔被问&#xff0c;程序员都能开发公司的软件了&#xff0c;为啥不做个软件自己卖。作为写了近10年代码的程序员&#xff0c;来分享一下这个话题。 据了解&#xff0c;每个程序员都想过去做一款自己的产品去赚钱&#xff0c;包括我。有人只是想过&#xff0c;有人去做过了&a…

配置VM开机自启动

1. 在此电脑-右键选择“管理”-服务和应用程序-服务中找到VMware Workstation Server服务&#xff08;新版名称也可能是VMware自启动服务&#xff0c;自己找一下&#xff0c;服务属性里有描述信息的&#xff09;&#xff0c;将其启用并选择开机自动启动 新版参考官方文档&…

蓝桥杯【第15届省赛】Python B组

这题目难度对比历届是相当炸裂的简单了…… A&#xff1a;穿越时空之门 【问题描述】 随着 2024 年的钟声回荡&#xff0c;传说中的时空之门再次敞开。这扇门是一条神秘的通道&#xff0c;它连接着二进制和四进制两个不同的数码领域&#xff0c;等待着勇者们的探索。 在二进制…

ReactRouter

React-Router 概念&#xff1a;一个路劲path对应一个组件component 当我们在浏览器中访问一个path的时候&#xff0c;path对应的组件会在页面中进行渲染路由语法&#xff1a; import {createBrowserRouter, RouterProvider} from react-router-dom// 1. 创建router实例对象并…

【算法刷题 | 回溯思想 02】4.12(电话号码的字母组合)

文章目录 4.电话号码的字母组合4.1问题4.2解法&#xff1a;回溯4.2.1回溯思路&#xff08;1&#xff09;函数返回值以及参数&#xff08;2&#xff09;终止条件&#xff08;3&#xff09;遍历过程 4.2.2代码实现 4.电话号码的字母组合 4.1问题 给定一个仅包含数字 2-9 的字符…

threejs 基础知识点汇总

threejs 基础知识点汇总 之前写了几篇博文&#xff0c;但是我觉得写的不好&#xff0c;我今天再补充一篇还不好的&#xff0c;把基础知识点汇总一下&#xff0c;不写运行的代码了&#xff0c;只写关键代码&#xff0c;但是看了之前我写的那几篇&#xff0c;看这篇的话问题其实不…

jdk17 你还想用ScriptEngineManager来执行js代码?

今天要用java来执行配置表的js代码&#xff0c;用 ScriptEngine javaScriptEngine new ScriptEngineManager().getEngineByName(“javascript”); 一直抛异常&#xff1a;Cannot invoke “javax.script.ScriptEngine.eval(String)” because “javaScriptEngine” is null 网上…

简单瞎搞题(位运算优化背包问题)

题目链接 这可不是瞎搞&#xff0c;出题人是有bear来。查资料时遇见的例题&#xff0c;当练习写一下。做法是位运算bitset优化的背包。 思路&#xff1a; 相当于有 n n n 组&#xff0c;每组选一个物品&#xff0c;然后问最后得到的重量之和是多少。不看位运算优化的话&…

Springboot集成Elastic-job

ElasticJob 通过弹性调度、资源管控、以及作业治理的功能&#xff0c;打造一个适用于互联网场景的分布式调度解决方案&#xff0c;并通过开放的架构设计&#xff0c;提供多元化的作业生态。 1 项目集成 1.1 springboot项目配置 导入依赖&#xff1a; <!--mysql连接基本配…

SSL证书添加与ICP备案,对于SpringBoot的要求

配置了SSL证书之后&#xff0c;在SpringBoot的resources文件夹里的application.properties会添加以下代码&#xff1a; server.port443 不需要添加server.address。不然会报错。 https类型的请求默认在Postman里面不可请求。 经过SSL证书处理的网页&#xff0c;链接中使默认…

【kears】keras使用介绍

文章目录 一.特点二.keras如何支持TensorFlow、CNTK 和 Theano2.1 使用 TensorFlow 后端引擎训练和评估模型2.2 使用 TensorFlow 后端引擎训练和评估模型2.3 使用 Theano后端引擎训练和评估模型2.4 不同深度学习框架如何选择 三.使用步骤3.1 导入库3.2 构建模型3.3 编译模型3.4…