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

news2024/11/26 15:47:20

文章目录

    • 一、原理分析
      • 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-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)

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

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

相关文章

注册信息合理性验证

表单是网页中的一个重要功能,主要用于用户信息的收集。使用JavaScript进行表单验证对于提升用户体验、减轻服务器负担、确保数据准确性、增强安全性和提高开发效率等方面都具有重要意义。本文详细敍述进行合理化验化必要性和具体实现方法。 一 表单项合理性必要性 主要体现在…

4款专业音频在线剪辑工具帮你开启创意之路。

音频在线剪辑工具能够为我们提供很大的便利&#xff0c;对于不管是专业的音乐制作人还是音频创作爱好者来说&#xff0c;都能借助一些音频编辑工具来充分发挥自己的创意。所以这一次&#xff0c;我要给大家介绍几个专业方便的音频剪辑工具。 1、福昕音频在线 直达链接&#x…

pdf页面提取全攻略,试试这几个简单方法,提升工作效率(收藏篇)

怎么提取pdf页面&#xff1f;在日常的办公生活中&#xff0c;我们经常需要使用到pdf文件&#xff0c;因此我们经常需要对PDF文档进行一些页面处理&#xff0c;比如提取PDF文件中的其中一个页面。那要怎么提取pdf文件中的其中一页呢&#xff1f;其实很简单&#xff0c;下面分享几…

【计算机网络】单播帧和广播帧在一个局域网内部的传播过程

我们引入这样的一个模型。 路由器可以连接多个网络&#xff0c;在路由器的这一端&#xff0c;我们用交换机集线器连接了很多节点。 这些节点共同组成了一个局域网。 而路由器的另外两个端口又分别连接了其他的网络。MAC地址这个概念是数据链路层才拥有的东西&#xff0c;物理…

翻译新体验:四款在线翻译工具让你沟通更顺畅!

如果你还拿着手里的外文文件干瞪眼&#xff1f;别担心&#xff0c;今天&#xff0c;我要给大家介绍几款超给力的在线翻译工具&#xff0c;它们就像是你的语言小助手&#xff0c;随时待命&#xff0c;帮你搞定那些让人头疼的翻译问题&#xff01; 福昕在线翻译 直达链接&#…

不用求人,4个方法快速恢复小米手机删除短信

手机短信作为我们日常办理事情的重要验收通道&#xff0c;往往承载着许多重要的信息。然而&#xff0c;由于各种原因&#xff0c;我们可能会不小心删除了重要的短信。那么&#xff0c;小米手机用户如何恢复这些被删除的短信呢&#xff1f;接下来&#xff0c;我们将分点为您详细…

macOS 15 Sequoia dmg格式转用于虚拟机的iso格式教程

想要把dmg格式转成iso格式&#xff0c;然后能在虚拟机上用&#xff0c;最起码新版的macOS镜像是不能用UltraISO&#xff0c;dmg2iso这种软件了&#xff0c;你直接转放到VMware里绝对读不出来&#xff0c;办法就是&#xff0c;在Mac系统中转换为cdr&#xff0c;然后再转成iso&am…

打造自己的RAG解析大模型:(新技能)企业垂类数据标注(一)

在上一篇文章中&#xff0c;我们以通用版面分析服务为例&#xff0c;展示了从模型发布到API集成的完整流程。如果你成功完成了这些步骤&#xff0c;值得庆祝&#xff01;这不仅意味着你已成功安装PaddleX&#xff0c;还掌握了利用它发布OCR和目标检测等大模型服务的能力&#x…

基于vue框架的的驾校练习时段预约系统z94u5(程序+源码+数据库+调试部署+开发环境)文末可获取,系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,驾校教练,车辆信息,训练场,教练预约,时间段,预约取消,学员签到,学员签退 开题报告内容 基于Vue框架的驾校练习时段预约系统开题报告 一、研究背景与意义 随着汽车保有量的持续增长&#xff0c;驾驶培训需求日益旺盛。然而&#…

技术干货|热门仿真工具HyperWorks 的二次开发与 Python 结合,重构仿真新体验

目前市面上有许多热门仿真软件&#xff0c;其中HyperWorks是各大企业最常用的。目前HyperWorks发布了 2024 新版本&#xff0c;已经全面支持Python作为二次开发接口&#xff0c;对Python的支持已经在架构中引入了相应的模块&#xff0c;基本是百分百覆盖。借助Python本身的优势…

2022NOIP比赛总结

种花 1.本题是一道前缀和优化加上枚举的问题。先考虑 C 因为 F 是 C 下边随便加一个点&#xff0c;所以只要求出 C 就求出了 F 。 注意到&#xff0c;并没有要求上下行一样&#xff0c;唯一的要求是 C 的两个横要隔一行&#xff0c;这就是问题的突破点&#xff0c;这题很明显…

《DIY项目之“一只眼狗链”》:视频方案

项目背景 《DIY项目之“一只眼狗链”》合集主要记录完成一个DIY项目的所有过程。该合集预计更新频率为2~3周一篇&#xff08;同样属于一边做一边记录发布&#xff0c;时间上主要涉及PCB绘板、零部件采购、样品制作、编程等&#xff0c;存在一定的不可控性&#xff09;。 当前项…

若依微服务15 - RuoYi-Vue3 实现前端独立运行

正文开始&#xff1a; RuoYi-Vue3 使用 Vue3 Element Plus Vite 技术栈。 GitHub 开源地址&#xff1a;https://github.com/yangzongzhuan/RuoYi-Vue3 本文介绍使用若依提供的在线后端接口&#xff0c;仅启动前端项目并进行界面开发&#xff0c;而无需启动后端服务。 一、克隆…

【ROS】详解ROS文件系统

参考&#xff1a;ROS入门笔记&#xff08;七&#xff09;&#xff1a;详解ROS文件系统 - 少云清的文章 - 知乎 https://zhuanlan.zhihu.com/p/338042120 ROS文件目录 这里的软件包指的是src下的文件夹&#xff0c;因为在ROS下创建软件包的流程如下&#xff1a; 把软件包…

Unity游戏上传微信小游戏步骤

准备一个小程序账号&#xff0c;在首页设置服务类目为小游戏&#xff08;需要新创建的小程序才能设置&#xff0c;之前设置过的不能更改为小游戏&#xff09; AppID(小程序ID) 在网页左下角点击进入账号设置-基本设置 下拉找到小程序Id(后面用到) 点击进入下载微信开发者…

SAP 根据不同生产版本创建销售预测简介

SAP 根据不同生产版本创建销售预测简介 业务场景前台操作1、创建BOM2、创建工艺路线3、创建生产版本4、创建销售预测5、调整销售预测6、查看物料需求业务场景 很多工厂一个物料可能会存在多个BOM,当有多个BOM存在的情况下就会存在多个生产版本,当创建计划独立需求的时候,系…

【java batik_使用BATIK解析SVG生成PNG图片】

矢量图的介绍及应用场景 矢量图是什么意思&#xff1f; 矢量图&#xff0c;也称为向量图&#xff0c;英文名字是Vector graphics。 矢量图是一种基于矢量的图形&#xff0c;由一系列的线段和曲线组成。由数学公式和算法生成的。这意味着矢量图可以在任何分辨率下清晰地显示&…

浅谈钓鱼攻防之道-制作免杀excel文件钓鱼

如果我告诉你我很厉害&#xff0c;也许你会说我在吹牛。但是如果我告诉你我并不厉害&#xff0c;你肯定知道我在撒谎。 1、CSV注入之RCE CSV公式注入(CSV Injection)是一种会造成巨大影响的攻击向量&#xff0c;攻击这可以向Excel文件中注入可以输出或以CSV文件读取的恶意攻击…

Linux Shell 实现一键部署mariadb11.6

mariadb MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,使用XtraDB来代替MySQL的InnoDB。 MariaDB由MySQL的创始人Michael Widenius主导开发…

在 Elasticsearch 中顺利管理季节性时间变化

作者&#xff1a;来自 Elastic Valeriy Khakhutskyy, James Gowdy 用于 Elasticsearch 异常检测的新夏令时日历。 每年春季和秋季两次&#xff0c;许多国家/地区都会调整时钟以更好地利用日光。这些时钟调整不仅会带来时差和 “困倦的星期一” 的感觉&#xff0c;还会带来来自…