SpringMVC上传下载文件解读

知识点

文件上传(File Upload):

  1. 创建一个控制器方法,使用 MultipartFile 参数来接收上传的文件。
  2. 在 Spring 配置文件中配置一个 MultipartResolver,常用的实现类是 CommonsMultipartResolver。
  3. 在 MultipartResolver 的配置中设置最大允许上传文件的大小。
  4. 在控制器方法中,使用 MultipartFile 的方法获取上传文件的信息,如文件名、大小、内容等。
  5. 使用 MultipartFile 的 transferTo() 方法将上传的文件保存到指定位置。

文件下载(File Download):

  1. 创建一个控制器方法,返回类型为 ResponseEntity<byte[]>,表示要下载的文件。
  2. 使用 HttpHeaders 类设置响应的头信息,包括文件名、文件类型等。
  3. 使用 Java IO 或其他工具类读取要下载的文件,并将内容设置到 ResponseEntity<byte[]> 中的字节数组中。
  4. 将包含文件内容和响应头信息的 ResponseEntity<byte[]> 对象作为控制器方法的返回值。

实现步骤

首先,在前端需要定义一个HTML表单来实现上传文件的功能:

<form action="upload" method="post" enctype="multipart/form-data"><input type="file" name="file"/><button type="submit">上传文件</button>
</form>

注意,表单的enctype属性必须设置为multipart/form-data,否则无法上传文件。

接下来,在后端需要编写控制器方法来处理上传文件的请求:

@Controller
public class FileController {@RequestMapping(value = "/upload", method = RequestMethod.POST)public String upload(@RequestParam("file") MultipartFile file) throws IOException {// 获取上传文件的名称String fileName = file.getOriginalFilename();// 文件保存路径String filePath = "path/to/save/" + fileName;// 将文件保存到磁盘上file.transferTo(new File(filePath));return "redirect:/success.html";}
}

在上述代码中,@RequestParam("file")注解表示获取名为file的上传文件。MultipartFile类是Spring提供的文件上传类,可以通过该类的方法获取上传文件的名称、大小等属性,并将文件保存到磁盘上。

在后端下载文件时,我们需要编写一个控制器方法来返回文件的字节数组:

@Controller
public class FileController {@RequestMapping("/download")public ResponseEntity<byte[]> download() throws IOException {// 获取要下载的文件路径String filePath = "path/to/download/file";// 读取文件内容到字节数组中byte[] bytes = Files.readAllBytes(Paths.get(filePath));// 构造响应头部信息,包括下载文件名和文件类型HttpHeaders headers = new HttpHeaders();headers.setContentDispositionFormData("attachment", "filename.txt");headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);// 返回字节数组和响应头部信息return new ResponseEntity<>(bytes, headers, HttpStatus.OK);}
}

在上述代码中,通过Files.readAllBytes()方法将文件内容读取到字节数组中,并使用ResponseEntity<byte[]>类封装字节数组和响应头部信息,最终返回给客户端进行下载。

在前端需要定义一个下载链接,用于触发下载文件的操作:

<a href="download">下载</a>

当用户点击该链接时,浏览器会发送一个请求到服务器,调用上述控制器方法来返回文件内容。浏览器会根据响应头部信息,自动弹出保存文件的对话框,让用户选择保存文件的位置。

可直接使用的Demo示例

@Controller
public class FileController {/*** 文件上传*/@RequestMapping("fileload")public String fileLoad(MultipartFile[] files,HttpServletRequest request) throws Exception {//设置上传的文件所存放的路径String path = request.getServletContext().getRealPath("/") + "files/";ObjectMapper mapper = new ObjectMapper();if (files != null && files.length > 0) {//循环获取上传的文件for (MultipartFile file : files) {//获取上传文件的名称String filename = file.getOriginalFilename();ArrayList<Resource> list = new ArrayList<>();//读取files.json文件中的文件名称String json = JSONFileUtils.readFile(path + "/files.json");if (json.length() != 0) {//将files.json的内容转为集合list = mapper.readValue(json,new TypeReference<List<Resource>>() {});for (Resource resource : list) {//如果上传的文件在files.json文件中有同名文件,将当前上传的文件重命名,以避免重名if (filename.equals(resource.getName())) {String[] split = filename.split("\\.");filename = split[0] + "(1)." + split[1];}}}// 文件保存的全路径String filePath = path + filename;// 保存上传的文件file.transferTo(new File(filePath));list.add(new Resource(filename));json = mapper.writeValueAsString(list); //将集合中转换成json//将上传文件的名称保存在files.json文件中JSONFileUtils.writeFile(json, path + "/files.json");}request.setAttribute("msg", "(上传成功)");return "forward:fileload.jsp";}request.setAttribute("msg", "(上传失败)");return "forward:fileload.jsp";}@ResponseBody@RequestMapping(value = "/getFilesName",produces = "text/html;charset=utf-8")public String getFilesName(HttpServletRequest request,HttpServletResponse response) throws Exception {String path = request.getServletContext().getRealPath("/") + "files/files.json";String json = JSONFileUtils.readFile(path);return json;}/*** 根据浏览器的不同进行编码设置,返回编码后的文件名*/public String getFileName(HttpServletRequest request,String filename) throws Exception {BASE64Encoder base64Encoder = new BASE64Encoder();String agent = request.getHeader("User-Agent");if (agent.contains("Firefox")) {// 火狐浏览器filename = "=?UTF-8?B?" + new String(base64Encoder.encode(filename.getBytes("UTF-8"))) + "?=";} else {// IE及其他浏览器filename = URLEncoder.encode(filename, "UTF-8");}return filename;}/*** 文件下载*/@RequestMapping("/download")public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,String filename) throws Exception {System.out.println("123");System.out.println(filename);filename = java.net.URLDecoder.decode(filename, "utf-8");System.out.println(filename);// 指定要下载的文件所在路径String path = request.getServletContext().getRealPath("/files/");// 创建该文件对象System.out.println(filename);File file = new File(path + File.separator + filename);// 设置响应头HttpHeaders headers = new HttpHeaders();filename = this.getFileName(request, filename);// 通知浏览器以下载的方式打开文件headers.setContentDispositionFormData("attachment", filename);// 定义以流的形式下载返回文件数据System.out.println(filename);headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);// 使用Sring MVC框架的ResponseEntity对象封装返回下载数据return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);}}

文件上传功能:

文件上传方法名为 fileLoad,通过 @RequestMapping 注解指定了请求地址为 "fileload"。该方法使用了 Spring 框架提供的 MultipartFile 类型来接收上传的文件,同时通过 HttpServletRequest 对象获取当前请求的上下文路径,并在该路径下创建一个名为 "files" 的文件夹用于保存上传的文件。该方法还使用了 Jackson 库中的 ObjectMapper 类将集合对象转化为 JSON 格式字符串,并通过封装好的 JSONFileUtils 工具类写入到 files.json 文件中保存。

文件下载功能:

文件下载方法名为 fileDownload,通过 @RequestMapping 注解指定了请求地址为 "download"。该方法通过 HttpServletRequest 对象获取当前请求的上下文路径,然后构造一个文件对象,通过 ResponseEntity 类型封装该文件返回给客户端进行下载。在该方法中还有一个 getFileName 方法,用于在不同浏览器中对文件名进行编码处理,避免出现乱码问题。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>文件上传和下载</title><script src="${ pageContext.request.contextPath }/js/jquery-3.6.0.js" type="text/javascript"></script>
</head>
<body>
<table border="1"><tr><td width="200" align="center">文件上传${msg}</td><td width="300" align="center">下载列表</td></tr><tr><td height="100"><form action="${pageContext.request.contextPath}/fileload"method="post" enctype="multipart/form-data"><input type="file" name="files" multiple="multiple"><br/><input type="reset" value="清空"/><input type="submit" value="提交"/></form></td><td id="files"></td></tr>
</table>
</body>
<script>$(document).ready(function () {var url = "${pageContext.request.contextPath }/getFilesName";$.get(url, function (files) {var files = eval('(' + files + ')');for (var i = 0; i < files.length; i++) {result=files[i].namefiles[i].name=encodeURI(files[i].name);files[i].name=encodeURI(files[i].name);$("#files").append("<li>" +"<a href=${pageContext.request.contextPath }" + "" +"\\" + "download?filename=" + files[i].name + ">" +result + "</a></li>");}})})
</script>
</html>

页面包含一个表格,其中第一行为文件上传的部分,第二行为文件下载列表的部分。在文件上传的部分,用户可以选择要上传的文件,并通过提交按钮将文件上传到服务器。在文件下载列表的部分,页面通过 AJAX 异步请求获取服务器端返回的文件列表数据,并使用 jQuery 库对数据进行处理和展示。

<script> 标签中的 JavaScript 代码中,首先通过 $.get() 方法发送 GET 请求获取服务器返回的文件列表数据,然后遍历文件列表,将每个文件的名称作为链接展示在页面上。点击链接时,会跳转到下载功能的地址,并将文件名作为参数传递给下载功能。需要注意的是,为了避免文件名中的特殊字符引起的问题,JavaScript 代码中使用了 encodeURI() 方法对文件名进行编码处理。

演示具体:

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

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

相关文章

laravel8模块化开发laravel-modules

laravel8模块化开发laravel-modules 在laravel目录下打开git输入两行命令 $ composer require nwidart/laravel-modules $ php artisan module:make Admin 这个Admin就是文件名

用Pyinstaller打包深度学习算法为独立的可执行程序

前言&#xff1a;随着深度学习算法的流行&#xff0c;在传统工业软件计算领域&#xff0c;传统算法逐渐被深度学习算法给代替&#xff0c;但由于基于python的深度学习算法十分依赖python环境以及例如Pytorch、Scikit-learning、Keras等机器学习库&#xff0c;将深度学习算法运用…

西南科技大学数字电子技术实验五(用计数器设计简单秒表)预习报告

一、计算/设计过程 说明&#xff1a;本实验是验证性实验&#xff0c;计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程&#xff0c;越详细越好。用公式输入法完成相关公式内容&#xff0c;不得贴手写图片。&#xff08;注意&#xff1a;从抽象公式直接得出结…

UE5 PlaceActor

⚠️ 重点 PlaceActors 需在引擎初始化之后 但&#xff0c;单为这一个功能&#xff0c;更改整个模块的启动顺序&#xff0c;也不太划算 更好的办法是&#xff0c;启动顺序保持正常&#xff08;如"LoadingPhase": "Default" &#xff09;&#xff0c;然后…

Java EE 多线程之线程安全的集合类

文章目录 1. 多线程环境使用 ArrayList1. 1 Collections.synchronizedList(new ArrayList)1.2 CopyOnWriteArrayList 2. 多线程环境使用队列2.1 ArrayBlockingQueue2.2 LinkedBlockingQueue2.3 PriorityBlockingQueue2.4 TransferQueue 3. 多线程环境使用哈希表3.1 Hashtable3.…

innerHTML、innerText、textContent有什么区别

innerHTML、innerText、textContent有什么区别 在 HTML 中&#xff0c;innerHTML、innerText、 和textContent是 DOM&#xff08;文档对象模型&#xff09;的属性。它们允许我们读取和更新 HTML 元素的内容。 但它们在包含的内容以及处理 HTML 标签的方式有不同的行为。 读完…

分布式事务seata使用示例及注意事项

分布式事务seata使用示例及注意事项 示例说明代码调用方&#xff08;微服务A&#xff09;服务方&#xff08;微服务B&#xff09; 测试测试一 &#xff0c;seata发挥作用&#xff0c;成功回滚&#xff01;测试二&#xff1a;处理feignclient接口的返回类型从Integer变成String,…

【Spring Boot】快速入门

一、引言 1、什么是spring boot&#xff1f; Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。通过这种方式&#xff…

【RocketMQ-Install】Windows 环境下安装 RocketMQ 及基础命令的使用

【RocketMQ-Install】Windows 环境下 安装本地 RocketMQ 及基础命令的使用 1&#xff09;下载 RocketMQ 安装包1.1.官网下载&#xff08;推荐&#xff09;1.2.Git 下载1.3.安装环境要求说明 2&#xff09;Windows 安装3&#xff09;基础命令测试 1&#xff09;下载 RocketMQ 安…

多分类预测 | MATLAB实现CNN-LSTM-Attention多输入分类预测

分类预测 | MATLAB实现CNN-LSTM-Attention多输入分类预测 分类效果 需要源码和数据的私信&#xff08;微微有偿取哦&#xff09;

通义千问 Qwen-72B-Chat在PAI-DSW的微调推理实践

01 引言 通义千问-72B&#xff08;Qwen-72B&#xff09;是阿里云研发的通义千问大模型系列的720亿参数规模模型。Qwen-72B的预训练数据类型多样、覆盖广泛&#xff0c;包括大量网络文本、专业书籍、代码等。Qwen-72B-Chat是在Qwen-72B的基础上&#xff0c;使用对齐机制打造的…

主宰无双H5:WIN学习手工服务端通用视频教程及GM授权物品后台,支持三网H5玩法介绍

标题&#xff1a;主宰无双H5&#xff08;游戏源码&#xff09;&#xff1a;WIN学习手工服务端通用视频教程及GM授权物品后台&#xff0c;支持三网H5玩法的百科 一、引言 随着互联网的快速发展&#xff0c;H5游戏逐渐成为人们休闲娱乐的重要方式。主宰无双H5游戏源码作为一款深…

Android解决报错 superclass access check failed: class

Android解决报错 superclass access check failed: class 前言&#xff1a; 最近在打开之前的项目demo时&#xff0c;出现一个错误Cause: superclass access check failed: class butterknife.compiler.ButterKnifeProcessor$RScanner 1.错误信息如下&#xff1a; Executio…

《Linux C编程实战》笔记:目录操作

目录的创建和删除 mkdir函数 #include <sys/stat.h> #include <sys/types.h> int mkdir(const char *pathname, mode_t mode); mkdir创建一个新的空目录。空目录中会自动创建.和..目录项。所创建的目录的存取许可权由mode (mode &~umask)指定。 新创建目录的…

[Linux] LVS负载均衡群集+NAT部署

一、LVS负载均衡群集知识 1.1 群集的的定义及意义 Cluster&#xff0c;集群&#xff08;也称群集&#xff09;由多台主机构成&#xff0c;但对外只表现为一一个整体&#xff0c;只提供一-个访问入口(域名或IP地址)&#xff0c; 相当于一台大型计算机。 群集的作用&#xff1…

vue3使用Mars3D写区块地图

效果图 引入相关文件 因为我也是第一次使用&#xff0c;所以我是把插件和源文件都引入了&#xff0c;能使用启动 源文件 下载地址&#xff1a; http://mars3d.cn/download.html 放入位置 在index.html中引入 <!--引入cesium基础lib--><link href"/static/C…

Kubernetes 容器编排 -- 1

前言 知识扩展 早在 2015 年 5 月&#xff0c;Kubernetes 在 Google 上的搜索热度就已经超过了 Mesos 和 Docker Swarm&#xff0c;从那儿之后更是一路飙升&#xff0c;将对手甩开了十几条街,容器编排引擎领域的三足鼎立时代结束。 目前&#xff0c;AWS、Azure、Google、阿里…

软考科目如何选择?

软考科目繁多&#xff0c;让许多学弟学妹感到困惑&#xff0c;不知道该选择哪个科目。以下是一些建议&#xff0c;可以根据个人实际需求选择备考的科目。 1、初级是可选的 软考初级非常简单&#xff0c;适合刚刚入门学习的朋友报考。对于一些有基础的朋友&#xff0c;建议直接…

【从零开始学习--设计模式--装饰者模式】

返回首页 前言 感谢各位同学的关注与支持&#xff0c;我会一直更新此专题&#xff0c;竭尽所能整理出更为详细的内容分享给大家&#xff0c;但碍于时间及精力有限&#xff0c;代码分享较少&#xff0c;后续会把所有代码示例整理到github&#xff0c;敬请期待。 此章节介绍装…

java实现局域网内视频投屏播放(二)爬虫

代码链接 视频播放原理 大多视频网站使用的是m3u8&#xff0c;m3u8其实不是一个真正的视频文件&#xff0c;而是一个视频播放列表&#xff08;playlist&#xff09;。它是一种文本文件&#xff0c;里面记录了一系列的视频片段&#xff08;segment&#xff09;的网络地址。这些…