SpringMVC上传下载文件解读

news/2024/5/17 20:09:22/文章来源:https://blog.csdn.net/m0_62436868/article/details/134992592

知识点

文件上传(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.luyixian.cn/news_show_379774.aspx

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

相关文章

vscode

文章目录 变量引用Multi-selections(multi-cursor)Column (box) selection在正则表达式替换中改变大小写tasks.jsonlaunch.json vscode工作空间下有一个.vscode文件夹&#xff0c;该文件夹下放置了vscode的配置文件&#xff0c;主要有&#xff1a; settings.json : vscode的设置…

多维时序 | MATLAB实现RIME-CNN-BiLSTM-Multihead-Attention多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现RIME-CNN-BiLSTM-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现RIME-CNN-BiLSTM-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现RIME-…

Kibana搜索数据利器:KQL与Lucene

文章目录 一、搜索数据二、KQL查询1、字段搜索2、逻辑运算符3、通配符4、存在性检查5、括号 三、Lucene查询1、字段搜索2、逻辑运算符3、通配符4、范围搜索5、存在性检查6、括号 四、总结 一、搜索数据 默认情况下&#xff0c;您可以使用 Kibana 的标准查询语言&#xff0c;该…

JAVA:深入探讨Java 8 Stream的强大功能与用法

1、简述 Java 8引入了Stream API&#xff0c;为处理集合数据提供了一种更为强大和灵活的方式。Stream是一种抽象的数据结构&#xff0c;它允许你以一种声明性的方式处理数据集合。与传统的集合操作不同&#xff0c;Stream并不是一个存储数据的数据结构&#xff0c;而是在源数据…

【Spring】@SpringBootApplication注解解析

前言&#xff1a; 当我们第一次创建一个springboot工程时&#xff0c;我们会对启动类&#xff08;xxxApplication&#xff09;有许多困惑&#xff0c;为什么只要运行启动类我们在项目中自定义的bean无需配置类配置&#xff0c;扫描就能自动注入到IOC容器中&#xff1f;为什么我…

GO的sql注入盲注脚本

之间学习了go的语法 这里就开始go的爬虫 与其说是爬虫 其实就是网站的访问如何实现 因为之前想通过go写sql注入盲注脚本 发现不是那么简单 这里开始研究一下 首先是请求网站 这里貌似很简单 package mainimport ("fmt""net/http" )func main() {res, …

推荐算法:HNSW【推荐出与用户搜索的类似的/用户感兴趣的商品】

HNSW算法概述 HNSW&#xff08;Hierarchical Navigable Small Word&#xff09;算法算是目前推荐领域里面常用的ANN&#xff08;Approximate Nearest Neighbor&#xff09;算法了。其目的就是在极大量的候选集当中如何快速地找到一个query最近邻的k个元素。 要找到一个query的…

Firmware Analysis Plus (Fap)固件模拟安装教程(最新)

最近在搞IoT的研究&#xff0c;但是难在设备比较难弄&#xff0c;只有固件&#xff0c;而没有设备&#xff0c;买吧&#xff0c;又太费钱&#xff0c;不划算。好在有很多项目可以在模拟环境中运行固件。但是几乎没有一个平台能够模拟所有硬件设备。IoT产品的架构也不尽相同。 …

企业计算机服务器中了halo勒索病毒如何解密,halo勒索病毒恢复流程

网络技术的不断发展与应用&#xff0c;为企业的生产运营提供了极大便利&#xff0c;越来越多的企业使用数据库存储企业的重要数据&#xff0c;方便工作与生产&#xff0c;但网络是一把双刃剑&#xff0c;网络安全威胁一直存在&#xff0c;并且网络威胁的手段也在不断升级。在本…

C++笔记之重载和重写辨别

C笔记之重载和重写辨别 code review! 文章目录 C笔记之重载和重写辨别重载&#xff08;overloading&#xff09;重写&#xff08;Overriding&#xff09; 在C中&#xff0c;重载&#xff08;overloading&#xff09;和重写&#xff08;overriding&#xff09;是面向对象编程中…

Kotlin 笔记 -- Kotlin 语言特性的理解(二)

都是编译成字节码&#xff0c;为什么 Kotlin 能支持 Java 中没有的特性&#xff1f; kotlin 有哪些 Java 中没有的特性&#xff1a; 类型推断、可变性、可空性自动拆装箱、泛型数组高阶函数、DSL顶层函数、扩展函数、内联函数伴生对象、数据类、密封类、单例类接口代理、inter…

交互过程中影响信息质量好坏的因素

人机交互是指人与计算机之间的交流和互动&#xff0c;而人人交流是指人与人之间的交流和互动。在信息质量方面&#xff0c;人机交互通常更为准确和精确&#xff0c;而人人交流可能存在误解、模糊和歧义。 人机交互的信息传递往往通过明确的界面、符号和指令等方式进行。计算机可…

WPF 显示PDF、PDF转成图片

1.NuGet 安装 O2S.Components.PDFView4NET.WPF 2.添加组件 工具箱中&#xff0c;空白处 右键&#xff0c;选择项 WPF组件 界面&#xff0c;选择NuGet安装库对面路径下的 O2S.Components.PDFView4NET.WPF.dll 3.引入组件命名空间&#xff0c;并使用 <Windowxmlns"htt…

C、C++、C#的区别概述

C、C、C#的区别概述 https://link.zhihu.com/?targethttps%3A//csharp-station.com/understanding-the-differences-between-c-c-and-c/文章翻译源于此链接 01、C语言 ​ Dennis Ritchie在1972年创造了C语言并在1978年公布。Ritchie设计C的初衷是用于开发新版本的Unix。在那之…

uni-app 微信小程序之好看的ui登录页面(三)

文章目录 1. 页面效果2. 页面样式代码 更多登录ui页面 uni-app 微信小程序之好看的ui登录页面&#xff08;一&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;二&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;三&#xff09; uni-app 微信小程…

【亚马逊云科技】通过高性能低延迟对象存储 S3实现网站资源托管

本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 文章目录 前言1 S3 介绍1.1 优点 2 使用步骤2.1 注册账户2.2 创建存储桶2.2.1 打开控制…

node14升级node16之后,webpack3项目无法启动处理

node从14升级到16之后&#xff0c;项目就无法启动了&#xff0c;研究了webpack3升级5&#xff0c;研究好几个小时都无法启动&#xff0c;最后发现&#xff0c;微微升级几个版本就可以了。webpack还是3 版本改了好多个的&#xff0c;但是不确定具体是哪几个起作用的&#xff0c;…

微搭低代码实现登录注册功能

目录 1 创建用户数据源2 实现登录逻辑3 搭建登录页面4 设置登录框5 实现登录的逻辑6 用户注册总结 原来产品在创建应用的时候可以创建模型应用&#xff0c;模型应用对应我们小程序的后端。最新的更新已经将模型应用的能力下线&#xff0c;那我们不得不自己实现一下后端的逻辑。…

idea__SpringBoot微服务11——整合Druid数据源(新依赖)(新注解)

整合JDBC 一、导入依赖二、配置Druid————————创作不易&#xff0c;如觉不错&#xff0c;随手点赞&#xff0c;关注&#xff0c;收藏(*&#xffe3;︶&#xffe3;)&#xff0c;谢谢~~ 接着 第10的 新注解&#xff1a; ConfigurationProperties ConfigurationPropert…

记录 | ubuntu源码编译安装/更新boost版本

一、卸载当前的版本 1、查看当前安装的boost版本 dpkg -S /usr/include/boost/version.hpp通过上面的命令&#xff0c;你就可以发现boost的版本了&#xff0c;查看结果可能如下&#xff1a; libboost1.54-dev: /usr/include/boost/version.hpp 2、删除当前安装的boost sudo …