当前位置: 首页 > news >正文

Spring Boot 实现文件上传下载功能

文章目录

    • 一、原理分析
      • 1.1 请求类型
      • 1.2 服务器解析
    • 二、功能实现
      • 2.1 创建项目并导入依赖
      • 2.2 文件上传功能实现
        • 2.2.1 文件上传 Service
        • 2.2.2 文件上传 Controller
      • 2.3 文件下载功能实现
        • 2.3.1 文件下载 Service
        • 2.3.2 文件下载 Controller
      • 2.4 文件上传前端代码(可选)
        • 2.4.1 上传文件的 HTML 表单
        • 2.4.2 访问前端页面
    • 三、功能测试
      • 3.1 测试文件上传
      • 3.2 测试文件下载
    • 参考资料

完整案例代码:java-demos/spring-boot-file at main · idealzouhu/java-demos (github.com)

一、原理分析

1.1 请求类型

文件上传通常使用 multipart/form-data 类型的 POST 请求。

  • multipart/form-data:用于在表单提交时上传文件的 MIME 类型。它允许将文件和其他表单字段组合在一起发送,服务器能识别出每个部分并提取出文件。

文件下载则只是简单的 GET 请求。在 Spring MVC 中,返回对象通常是 ResponseEntity 或者 HttpServletResponse 对象。

1.2 服务器解析

现有的 Web 框架都内置了处理文件上传的功能。在 Spring MVC 中, MultipartFile 是用来表示上传的文件,服务器会自动解析该文件并进行处理。

MultipartFile 的常用方法有:

  • getName():获取文件在服务器上的文件名,可能已经被服务器修改。
  • getOriginalFilename():获取文件在客户端上的原始文件名,没有被服务器修改。
  • getContentType():获取文件的内容类型。
  • isEmpty():判断文件是否为空。
  • getSize():获取文件大小(字节)。
  • getBytes():读取文件内容为字节数组。
  • getInputStream():获取文件内容的输入流。
  • getResource():将文件转换为资源对象。
  • transferTo(File dest):将文件内容传输到指定的目标文件。
  • transferTo(Path dest):将文件内容传输到指定的目标路径

二、功能实现

2.1 创建项目并导入依赖

在 start.springboot.io 创建项目,导入以下依赖。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.2 文件上传功能实现

将文件上传的具体逻辑抽象到一个 FileService 中,让 Controller 调用该服务处理上传请求。

2.2.1 文件上传 Service
@Service
public class FileService {/*** 上传文件** @param file* @return*/public String uploadFile(MultipartFile file) {// 检查文件是否为空if (file.isEmpty()) {return "上传失败,因为文件是空的。";}// 获取文件名和保存路径String fileName = file.getOriginalFilename();String filePath = "C:/uploads/"; // 自定义文件保存路径File dest = new File(filePath + fileName);// 确保目录存在if (!dest.getParentFile().exists()) {dest.getParentFile().mkdirs();}// 保存文件try {file.transferTo(dest);return "文件上传成功:" + fileName;} catch (IOException e) {e.printStackTrace();return "文件上传失败。";}}
}
2.2.2 文件上传 Controller
@RequiredArgsConstructor
@RestController
public class FileUploadController {private final FileService fileService;/*** 上传文件自动绑定到 MultipartFile 对象中** @param file 上传文件* @return*/@PostMapping("/upload")public String upload(@RequestParam("file") MultipartFile file) {return fileService.uploadFile(file);}
}

2.3 文件下载功能实现

将文件上传的具体逻辑抽象到一个 FileService 中,让 Controller 调用该服务处理上传请求。

2.3.1 文件下载 Service
@Service
public class FileService {/*** 下载文件** 根据文件名构建文件路径,并检查文件是否存在如果文件不存在,则返回404未找到的响应* 如果文件存在,将文件作为资源包装,并设置HTTP响应头以提示浏览器下载文件** @param fileName 要下载的文件名* @return 包含文件资源的响应实体,如果文件不存在则为404响应*/public ResponseEntity<Resource> downloadFile(String fileName) {// 构建文件路径String filePath = "C:/uploads/" + fileName;File file = new File(filePath);// 检查文件是否存在if (!file.exists()) {// 文件不存在,返回404未找到return ResponseEntity.notFound().build();}// 将文件包装为资源Resource resource = new FileSystemResource(file);// 创建HTTP响应头,用于指定文件下载HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");// 返回包含文件资源和响应头的响应实体return ResponseEntity.ok().headers(headers).body(resource);}
}
2.3.2 文件下载 Controller
@RequiredArgsConstructor
@RestController
public class FileDownloadController {private final FileService fileService;@GetMapping("/download")public ResponseEntity<Resource> downloadFile(@RequestParam String fileName) {return fileService.downloadFile(fileName);}
}

2.4 文件上传前端代码(可选)

该部分代码为 [2.2 文件上传功能实现](###2.2 文件上传功能实现) 的前端实现。

2.4.1 上传文件的 HTML 表单

创建 upload.html 文件,放在 src/main/resources/static 目录下。

<!DOCTYPE html>
<html>
<head><title>File Upload</title>
</head>
<body><h2>Upload a file</h2><form id="uploadForm"><label for="file">Choose file to upload:</label><input type="file" id="file" name="file" required /><br><br><button type="submit">Upload</button>
</form><script>document.getElementById('uploadForm').addEventListener('submit', function(event) {event.preventDefault();  // 防止表单的默认提交行为const fileInput = document.getElementById('file');const formData = new FormData();formData.append('file', fileInput.files[0]);// 使用 Fetch API 发送文件到后端fetch('/upload', {method: 'POST',body: formData}).then(response => response.text()).then(data => alert('File uploaded successfully: ' + data)).catch(error => console.error('Error uploading file:', error));});
</script></body>
</html>

其中,表单中 name="file" 指定了文件在请求体中的键,后端服务器将通过这个名称来获取文件数据。

2.4.2 访问前端页面

进入前端页面的 URL 为 http://localhost:8080/upload.html

在这里插入图片描述

三、功能测试

3.1 测试文件上传

使用 Postman 发送 POST 请求到 /upload,并选择一个文件进行上传。示例 URL 为

http://localhost:8080/upload

在这里插入图片描述

3.2 测试文件下载

使用 Postman 或 HTML 表单发送 POST 请求,下载指定的文件。

示例 URL 为 http://localhost:8080/download?fileName=demo.txt

在这里插入图片描述

参考资料

Java实战:Spring Boot 实现文件上传下载功能_springboot 文件下载-CSDN博客

Spring Boot文件上传与下载讲解与实战(超详细 附源码)-阿里云开发者社区 (aliyun.com)

相关文章:

Spring Boot 实现文件上传下载功能

文章目录 一、原理分析1.1 请求类型1.2 服务器解析 二、功能实现2.1 创建项目并导入依赖2.2 文件上传功能实现2.2.1 文件上传 Service2.2.2 文件上传 Controller 2.3 文件下载功能实现2.3.1 文件下载 Service2.3.2 文件下载 Controller 2.4 文件上传前端代码(可选)2.4.1 上传文…...

ArcGIS 10.8 安装教程(含安装包)

目录 一、ArcGIS10.8二、安装链接三、安装教程四、ArcGIS实战 &#xff08;一&#xff09;ArcGIS10.8 1. 概述 ArcGIS 10.8是由美国Esri公司开发的GIS平台&#xff0c;用于处理、分析、显示和管理地理数据&#xff0c;并实现数据共享。它具有新特性和功能&#xff0c;性能更…...

【小白学机器学习16】 概率论的世界观2: 从正态分布去认识世界

目录 1 从正态分布说起 1.1 正态分布的定义 1.2 正态分布的名字 1.3 正态分布的广泛&#xff0c;和基础性 2 正态分布的公式和图形 2.1 正态分布 2.2 标准正态分布 3 正态分布的认识的3个层次 3.1 第1层次&#xff1a;个体的某个属性的样本值&#xff0c;服从正态分布…...

Python 爬虫项目实战:爬取某云热歌榜歌曲

一、网络爬虫的定义 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;也成为网页蜘蛛或者网页机器人&#xff0c;是一种按照既定规则自动浏览网络并提取信息的程序。爬虫的主要用途包括数据采集、网络索以及内容抓取等。 二、爬虫基本原理 1、种子URL&#xff1a;爬…...

HCIP-HarmonyOS Application Developer 习题(十八)

&#xff08;判断&#xff09;1、在HarmonyOS有序公共事件中&#xff0c;高优先级订阅者可修改公共事件内容或处理结果&#xff0c;但不能终止公共事件处理。 答案&#xff1a;错误 分析&#xff1a;有序公共事件&#xff1a;主要场景是多个订阅者有依赖关系或者对处理顺序有要…...

操作系统学习笔记2.3互斥

文章目录 进程同步实现方式 进程互斥实现方式 软件实现方法硬件实现方法同步问题生产者-消费者问题问题描述解决方案代码解析 多生产者-多消费者问题问题描述 解决方案代码解析总结 抽烟者问题问题背景 同步与互斥的挑战解决方案实现步骤代码解释 关键点 进程同步 进程同步是指…...

LLM - 使用 Neo4j 可视化 GraphRAG 构建的 知识图谱(KG) 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142938982 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Neo4j …...

Linux 环境的搭建方式->远程登录->免密登录

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;Linux系统性学习_Jason_from_China的博客-CSDN博客 所属栏目&#xff1a;Linux知识点的补充_Jason_from_China的博客-CSDN博客 Linux 环境的搭建方式 Linux 环境的搭建主要有三种方式&#xff1a; 直接安…...

react18中的计算属性及useMemo的性能优化技巧

react18里面的计算属性和使用useMemo来提升组件性能的方法 计算属性 实现效果 代码实现 函数式组件极简洁的实现&#xff0c;就这样 import { useState } from "react"; function FullName() {const [firstName, setFirstName] useState("");const [la…...

Python 实现高效的 SM4 大文件加密解密实战指南20241024

Python 实现高效的 SM4 大文件加密解密实战指南 引言 在数据安全领域&#xff0c;使用对称加密算法如SM4进行数据保护非常常见。特别是当处理大文件时&#xff0c;合理的内存和块大小管理以及加密解密效率变得尤为重要。本文将分享如何使用Python进行大文件的SM4加密解密操作&…...

数据结构~红黑树

文章目录 一、红黑树的概念二、红黑树的定义三、红黑树的插入四、红黑树的平衡五、红黑树的验证六、红黑树的删除七、完整代码八、总结 一、红黑树的概念 红黑树是一棵二叉搜索树&#xff0c;他的每个结点增加⼀个存储位来表示结点的颜色&#xff0c;可以是红色或者黑色。通过…...

【ROS GitHub使用】

提示&#xff1a;环境配置为Ubuntu20.04&ROS Noetic 文章目录 前言一、创建工作空间目录二、尝试从GitHub上下载一个源码包&#xff0c;对它进行编译&#xff0c;运行这个源码包1.打开script文件夹&#xff0c;右键文件夹空白区域&#xff0c;选择在中端中打开&#xff1b;…...

批量处理文件权限:解决‘/usr/bin/chmod: Argument list too long’的有效方法

批量处理文件权限&#xff1a;解决‘/usr/bin/chmod: Argument list too long’的有效方法 错误原因解决方案1. 分批处理2. 使用xargs3. 增加ARG_MAX限制4. 使用脚本 结论 在Linux系统中&#xff0c;有时你可能会遇到这样的错误消息&#xff1a;“/usr/bin/chmod: Argument lis…...

数据结构——树——二叉树——大小堆

目录 1>>导言 2>>树 2.1>>树的相关术语 2.2>>树的表示和应用场景 3>>二叉树 3.1>>完全二叉树 3.2>>大小根堆 4>>结语 1>>导言 上篇小编将队列的内容给大家讲完了&#xff0c;这篇要步入新的篇章&#xff0c;请宝…...

Android Junit 单元测试 | 依赖配置和编译报错解决

问题 为什么在依赖中添加了testImplement在build APK的时候还是会报错&#xff1f;是因为没有识别到test文件夹是test源代码路径吗&#xff1f; 最常见的配置有: implementation - 所有源代码集(包括test源代码集)中都有该依赖库.testImplementation - 依赖关系仅在test源代码…...

ffmpeg视频滤镜: 裁剪-crop

滤镜简述 crop官网链接 > FFmpeg Filters Documentation crop滤镜可以对视频进行裁剪&#xff0c;并且这个滤镜可以接受一些变量比如时间和帧数&#xff0c;这样我们实现动态裁剪&#xff0c;从而实现一些特效。 滤镜使用 参数 out_w <string> ..…...

身份证归属地查询接口-在线身份证归属地查询-身份证归属地查询API

接口简介&#xff1a;输入身份证号码可查询到所属地区、出生年日月以及性别。 接口地址&#xff1a;https://www.wapi.cn/api_detail/60/167.html 在线核验&#xff1a;https://www.wapi.cn/icard.html 网站地址&#xff1a;https://www.wapi.cn 返回格式&#xff1a;json,xml,…...

ESP32 S3 怎么开发基于ESP-RTC的音视频实时交互的应用,用语AI陪伴的领域

在ESP32-S3平台上开发基于ESP-RTC的音视频实时交互应用&#xff0c;尤其是在AI陪伴领域&#xff0c;涉及到音视频数据的采集、编码、传输和解码。ESP32-S3 具备较强的处理能力&#xff0c;且拥有丰富的接口和模块支持&#xff0c;可以用来实现这种功能。以下是一个完整的开发方…...

车载测试分享:UDS诊断、ECU刷写、CAN一致性测试、网络通讯测试、CANoe使用、报文解析、问题定位分析

FOTA模块中OTA的知识点&#xff1a;1.测试过程中发现哪几类问题&#xff1f; 可能就是一个单键的ecu&#xff0c;比如升了一个门的ecu&#xff0c;他的升了之后就关不上&#xff0c;还有就是升级组合ecu的时候&#xff0c;c屏上不显示进度条。 2.在做ota测试的过程中&#xf…...

预算不够,怎么跟KOL砍价?(内附砍价模板)

​在当今的数字营销时代&#xff0c;海外红人&#xff08;KOL&#xff09;的影响力不容小觑。他们的一篇帖子、一个视频&#xff0c;甚至是一张照片&#xff0c;都有可能为企业带来巨大的流量和销量。 当企业满怀希望地找到一位粉丝众多、影响力强的KOL&#xff0c;准备洽谈合作…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...