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实战 (一)ArcGIS10.8 1. 概述 ArcGIS 10.8是由美国Esri公司开发的GIS平台,用于处理、分析、显示和管理地理数据,并实现数据共享。它具有新特性和功能,性能更…...

【小白学机器学习16】 概率论的世界观2: 从正态分布去认识世界
目录 1 从正态分布说起 1.1 正态分布的定义 1.2 正态分布的名字 1.3 正态分布的广泛,和基础性 2 正态分布的公式和图形 2.1 正态分布 2.2 标准正态分布 3 正态分布的认识的3个层次 3.1 第1层次:个体的某个属性的样本值,服从正态分布…...

Python 爬虫项目实战:爬取某云热歌榜歌曲
一、网络爬虫的定义 网络爬虫(Web Crawler),也成为网页蜘蛛或者网页机器人,是一种按照既定规则自动浏览网络并提取信息的程序。爬虫的主要用途包括数据采集、网络索以及内容抓取等。 二、爬虫基本原理 1、种子URL:爬…...

HCIP-HarmonyOS Application Developer 习题(十八)
(判断)1、在HarmonyOS有序公共事件中,高优先级订阅者可修改公共事件内容或处理结果,但不能终止公共事件处理。 答案:错误 分析:有序公共事件:主要场景是多个订阅者有依赖关系或者对处理顺序有要…...

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

LLM - 使用 Neo4j 可视化 GraphRAG 构建的 知识图谱(KG) 教程
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/142938982 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 Neo4j …...

Linux 环境的搭建方式->远程登录->免密登录
个人主页:Jason_from_China-CSDN博客 所属栏目:Linux系统性学习_Jason_from_China的博客-CSDN博客 所属栏目:Linux知识点的补充_Jason_from_China的博客-CSDN博客 Linux 环境的搭建方式 Linux 环境的搭建主要有三种方式: 直接安…...

react18中的计算属性及useMemo的性能优化技巧
react18里面的计算属性和使用useMemo来提升组件性能的方法 计算属性 实现效果 代码实现 函数式组件极简洁的实现,就这样 import { useState } from "react"; function FullName() {const [firstName, setFirstName] useState("");const [la…...
Python 实现高效的 SM4 大文件加密解密实战指南20241024
Python 实现高效的 SM4 大文件加密解密实战指南 引言 在数据安全领域,使用对称加密算法如SM4进行数据保护非常常见。特别是当处理大文件时,合理的内存和块大小管理以及加密解密效率变得尤为重要。本文将分享如何使用Python进行大文件的SM4加密解密操作&…...

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

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

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

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

Android Junit 单元测试 | 依赖配置和编译报错解决
问题 为什么在依赖中添加了testImplement在build APK的时候还是会报错?是因为没有识别到test文件夹是test源代码路径吗? 最常见的配置有: implementation - 所有源代码集(包括test源代码集)中都有该依赖库.testImplementation - 依赖关系仅在test源代码…...

ffmpeg视频滤镜: 裁剪-crop
滤镜简述 crop官网链接 > FFmpeg Filters Documentation crop滤镜可以对视频进行裁剪,并且这个滤镜可以接受一些变量比如时间和帧数,这样我们实现动态裁剪,从而实现一些特效。 滤镜使用 参数 out_w <string> ..…...
身份证归属地查询接口-在线身份证归属地查询-身份证归属地查询API
接口简介:输入身份证号码可查询到所属地区、出生年日月以及性别。 接口地址:https://www.wapi.cn/api_detail/60/167.html 在线核验:https://www.wapi.cn/icard.html 网站地址:https://www.wapi.cn 返回格式:json,xml,…...
ESP32 S3 怎么开发基于ESP-RTC的音视频实时交互的应用,用语AI陪伴的领域
在ESP32-S3平台上开发基于ESP-RTC的音视频实时交互应用,尤其是在AI陪伴领域,涉及到音视频数据的采集、编码、传输和解码。ESP32-S3 具备较强的处理能力,且拥有丰富的接口和模块支持,可以用来实现这种功能。以下是一个完整的开发方…...

车载测试分享:UDS诊断、ECU刷写、CAN一致性测试、网络通讯测试、CANoe使用、报文解析、问题定位分析
FOTA模块中OTA的知识点:1.测试过程中发现哪几类问题? 可能就是一个单键的ecu,比如升了一个门的ecu,他的升了之后就关不上,还有就是升级组合ecu的时候,c屏上不显示进度条。 2.在做ota测试的过程中…...

预算不够,怎么跟KOL砍价?(内附砍价模板)
在当今的数字营销时代,海外红人(KOL)的影响力不容小觑。他们的一篇帖子、一个视频,甚至是一张照片,都有可能为企业带来巨大的流量和销量。 当企业满怀希望地找到一位粉丝众多、影响力强的KOL,准备洽谈合作…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...