SpringBoot功能模块之实现单文件、多文件上传和下载

一、单文件上传

1.1MultipartFile

MultipartFile 是 Spring 框架中的一个接口,主要用于处理 HTTP 请求中的文件上传。它提供了一些方法来获取上传文件的信息和内容。  以下是 MultipartFile 的一些主要方法:  

  • getOriginalFilename():返回上传文件的原始文件名。
  • getName():返回表单中文件组件的名字。
  • getContentType():返回文件的 MIME 类型。
  • isEmpty():返回文件是否为空。
  • getSize():返回文件的大小,单位为字节。
  • getBytes():返回文件的内容,作为字节数组。
  • getInputStream():返回一个 InputStream,用于读取文件的内容。
  • transferTo(File dest):将上传的文件保存到目标文件中。
@PostMapping("/upload") // 定义一个处理文件上传的POST请求映射
public String handleFileUpload(@RequestParam("file") MultipartFile file) { // 接收名为"file"的文件参数
    String name = file.getOriginalFilename(); // 获取原始文件名
    try {
        file.transferTo(new File("/path/to/destination/" + name)); // 将文件保存到指定路径
        return "File uploaded successfully"; // 返回文件上传成功的提示信息
    } catch (IOException e) {
        e.printStackTrace(); // 打印异常堆栈信息
        return "Failed to upload file"; // 返回文件上传失败的提示信息
    }
}

File.separator 是系统相关的默认名称分隔符。在 UNIX 系统中,这个字段的值为 '/';在 Microsoft Windows 系统中,它为 '\'。 

private static final String ROOT_PATH = System.getProperty("user.dir") + File.separator + "files";

 System.getProperty("user.dir") 是 Java 系统属性,用于获取用户的当前工作目录。这通常是运行 JVM 的路径。 

1.2MIME 类型

MIME 类型是一种标准,用于表示文档、文件或字节流的性质和格式。 以下是一些常见的 MIME 类型:

  • text/plain:纯文本文件
  • text/html:HTML 文件
  • text/css:CSS 文件
  • text/javascript:JavaScript 文件
  • image/jpeg:JPEG 图像文件
  • image/png:PNG 图像文件
  • image/gif:GIF 图像文件
  • application/pdf:PDF 文件
  • application/msword:Microsoft Word 文件
  • application/vnd.ms-excel:Microsoft Excel 文件
  • application/vnd.ms-powerpoint:Microsoft PowerPoint 文件
  • application/json:JSON 数据
  • application/xml:XML 数据
  • application/zip:ZIP 压缩文件

这些只是一些常见的 MIME 类型,实际上 MIME 类型的数量非常多,可以表示各种各样的文件和数据格式。

 1.3Hutool插件

概述

Hutool是一个功能丰富的Java工具类库,它旨在简化Java开发中的常见任务。

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.25</version>
        </dependency>

Hutool提供了一系列的工具类和组件,具体如下:

  1. 文件操作:对文件的读写、复制、删除等进行封装,简化了文件处理流程。
  2. 流操作:对输入输出流的包装,使得流的处理更加便捷。
  3. 加密解密:提供多种加密解密算法的实现,如MD5、SHA等。
  4. 转码:支持字符串与字节数组之间的转换,以及不同编码格式之间的转换。
  5. 正则表达式:简化了正则表达式的使用,提供匹配和替换等功能。
  6. 线程操作:包括线程池管理、线程控制等。
  7. XML处理:简化了XML文档的解析、生成和查询。
  8. 缓存:提供简单的缓存机制,帮助提升程序性能。
  9. 定时任务:支持类似Crontab表达式的定时任务调度。
  10. 数据库操作:基于JDBC的封装,简化了数据库操作。
  11. 布隆过滤器:实现布隆过滤算法,用于高效判断一个元素是否属于某个集合。
  12. 切面编程:即使在非IOC环境下,也支持AOP编程。
  13. 多关键字查找:基于DFA模型的多关键字搜索实现。

Hutool的设计哲学是“小而全”,通过静态方法封装常用的功能,降低API的学习成本,提高开发效率,使Java代码更加优雅。它是Java项目中“util”包的良好替代品,可以节省开发人员在公用类和工具方法上的时间,让开发者更专注于业务逻辑。

  FileUtil 类

FileUtil 是 Hutool 工具包中的一个类,主要用于文件和目录的操作。它提供了一系列的静态方法,可以方便地进行文件的创建、复制、删除、移动、读取和写入等操作。

String originalFilename = file.getOriginalFilename();  // 文件的原始名称
String mainName = FileUtil.mainName(originalFilename);  // 获取文件主名称
String extName = FileUtil.extName(originalFilename); // 获取文件扩展名

在 FileController 类的 upload 方法中,上述使用了 FileUtil 的 mainName 和 extName 方法来获取上传文件的主名称和扩展名:

以下是 FileUtil 的一些主要方法:  

  • file(String path):根据文件路径创建 File 对象。
  • mkdir(String path):创建目录,如果父目录不存在,会一并创建。
  • copy(File src, File dest, boolean isOverride):复制文件或目录,通过第三个参数控制如果目标文件存在时是否覆盖。
  • move(File src, File dest, boolean isOverride):移动文件或目录,通过第三个参数控制如果目标文件存在时是否覆盖。
  • del(File file):删除文件或目录。
  • readUtf8String(File file):读取文件内容,返回 UTF-8 编码的字符串。
  • writeUtf8String(String content, File file):将字符串写入文件,编码为 UTF-8。
  • getAbsolutePath(File file):获取文件的绝对路径。
  • getName(File file):获取文件名或目录名。
  • getExtension(File file):获取文件的扩展名。
  • getSize(File file):获取文件或目录的大小。

这些只是 FileUtil 类的一部分方法,实际上它还提供了更多的方法,可以满足各种复杂的文件操作需求。 

1.4实现

 @Value("${ip:localhost}")
    String ip;

    @Value("${server.port:8083}")
    String port;

    private static final String ROOT_PATH =  System.getProperty("user.dir") + File.separator + "files";

    @PostMapping("/upload")
    public Result upload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {

            return Result.error("上传文件不能为空");
        }
        String originalFilename = file.getOriginalFilename();  // 文件的原始名称
        // aaa.png
        String mainName = FileUtil.mainName(originalFilename);  // 获取文件主名称aaa
        String extName = FileUtil.extName(originalFilename); // 获取文件扩展名png
        System.out.println("文件的原始名称:" + originalFilename);
        System.out.println("文件的主名称:" + mainName);
        try {
            if (!FileUtil.exist(ROOT_PATH)) {
                FileUtil.mkdir(ROOT_PATH);  // 如果当前文件的父级目录不存在,就创建
            }
            if (FileUtil.exist(ROOT_PATH + File.separator + originalFilename)) {  // 如果当前上传的文件已经存在了,那么这个时候我就要重名一个文件名称
                originalFilename = System.currentTimeMillis() + "_" + mainName + "." + extName;
            }
            File saveFile = new File(ROOT_PATH + File.separator + originalFilename);
            System.out.println("文件的保存路径:" + saveFile.getAbsolutePath());
            file.transferTo(saveFile);  // 存储文件到本地的磁盘里面去
            String url = "http://" + ip + ":" + port + "/file/download/" + originalFilename;
            return Result.success(url);  //返回文件的链接,这个链接就是文件的下载地址,这个下载地址就是我的后台提供出来的

            //另外一种思路
//            file.transferTo(new File(UPLOAD_DIR + fileName));
//            // 返回文件的下载链接
//            String fileDownloadUri = "/file/download?fileName=" + fileName;
//            return javax.xml.transform.Result.success(fileDownloadUri);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("上传文件失败");
        }
    }

测试

 二、文件下载

2.1URLEncoder

URLEncoder 是 Java 中的一个工具类,用于将字符串转换为 application/x-www-form-urlencoded MIME 格式。这种格式通常用于 HTTP 请求的查询字符串部分。 

以下是 `URLEncoder` 的一些常用方法:

1. `encode(String s, String enc)`: 这个方法用于将指定的字符串按照指定的编码方式进行转码。例如,`URLEncoder.encode("hello world", "UTF-8")` 将返回 "hello+world"。

2. `encode(String s)`: 这个方法已经被废弃,因为它使用平台默认的编码方式进行转码,这可能会导致不可预知的结果。建议使用 `encode(String s, String enc)` 方法。

以下是 `URLEncoder.encode(String s, String enc)` 方法的一个示例:

try {
    String original = "文件名 with spaces";
    String encoded = URLEncoder.encode(original, "UTF-8");
    System.out.println(encoded);  // 输出 "文件名+with+spaces"
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}

在这个示例中,空格被转换为 `+`。如果原始字符串中包含非 ASCII 字符或其他需要编码的字符,它们将被转换为 `%` 后跟两个十六进制数字的形式。

2.2实现

 @GetMapping("/download/{fileName}")
    public Result download(@PathVariable("fileName") String fileName, HttpServletResponse response) throws IOException {


       // response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileFullName, "UTF-8"));  // 附件下载
        String filePath = ROOT_PATH  + File.separator + fileName;

        if (!FileUtil.exist(filePath)) {
            return Result.error("文件不存在");
        }
        byte[] bytes = FileUtil.readBytes(filePath);
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(bytes);  // 数组是一个字节数组,也就是文件的字节流数组
        outputStream.flush();
        outputStream.close();
        System.out.println("文件下载成功");
        return Result.success();
    }

2.3配置介绍

在 Spring Boot 中,你可以在 application.properties 或 application.yml 文件中配置文件上传的最大大小。这是通过设置 spring.servlet.multipart.max-file-size 和 spring.servlet.multipart.max-request-size 属性来实现的。

  • spring.servlet.multipart.max-file-size:设置单个文件的最大大小。如果上传的文件超过这个大小,将会抛出异常。
  • spring.servlet.multipart.max-request-size:设置整个请求的最大大小。这包括所有的文件和其他表单数据。如果整个请求的大小超过这个值,将会抛出异常。
  • spring.servlet.multipart.file-size-threshold:这个属性用于设置写入磁盘的文件的大小阈值。如果上传的文件大小超过这个阈值,那么文件将会被写入到磁盘,而不是保存在内存中。这可以防止大文件上传消耗过多的内存。  
  • spring.servlet.multipart.location:这个属性用于设置临时文件的存储位置。当文件大小超过 file-size-threshold 时,文件将会被写入到这个位置。
servlet:
  multipart:
    max-file-size:20MB
    max-request-size:20MB

2.4文件预览

根据文件的类型区分的,一般是图片和 pdf 可以预览

response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(fileFullName, "UTF-8")); // 预览

Content-Disposition 是 HTTP 响应头部的一个字段,它定义了获取的资源如何处理。这个字段通常用于下载操作,告诉浏览器如何处理响应的内容。  Content-Disposition 主要有两个值:  

  • inline:这意味着资源应该直接在浏览器中显示,如果可能的话。例如,如果资源是一个图像或 PDF 文档,大多数浏览器都能够直接在浏览器窗口中显示这些类型的文件。  
  • attachment:这意味着资源应该被下载和保存到本地,而不是直接在浏览器中显示。  

Content-Disposition 还可以包含一个 filename 参数,这个参数可以指定一个默认的文件名,当用户保存资源时,浏览器会使用这个文件名。  例如,Content-Disposition: attachment; filename="filename.jpg" 这个头部会告诉浏览器下载资源并将其保存为 "filename.jpg"。

 

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

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

相关文章

vue 实现滚动导航

效果 实现 css 使用了 unocss 使界面滚动到给定元素的指定坐标位置 window.scrollTo({ top: 0 })使用了内边距避免最后数据高度不够 <main class"pb-100vh"></main>完整代码 <script lang"ts" setup> defineOptions({ name: DemoVi…

掌握Go语言:深入encoding/gob包的高效数据序列化

掌握Go语言&#xff1a;深入encoding/gob包的高效数据序列化 引言理解Gob和它的使用场景Gob的概念和设计目标Gob的适用场景和优势 开始使用Gob基本的Gob编码和解码示例代码编码&#xff08;序列化&#xff09;解码&#xff08;反序列化&#xff09; Gob编码高级应用自定义类型的…

Minecraft 1.20.1 Forge服务器保姆级搭建教程 (使用mcsm面板 | 两种启动方式)

MC Forge 服务器部署 使用 Linux 云服务器部署 Minecraft 1.20.1 Forge 服务器 目录 MC Forge 服务器部署看这篇教程之前&#xff0c;你需要准备好这篇教程的目标前期准备1. 环境需求&#xff1a;腾讯云、CentOS 7.9&#xff08;对于其他云服务商和 Linux 系统&#xff0c;操作…

[vscode]使用cmake时将命令行参数传递给调试目标

一、简介 本文介绍了在vscode中使用cmake工具时&#xff0c;如何传递参数给编译目标的方法。 前提&#xff1a;使用vscodecmake编译C/C程序。 二、方法 在.vscode/目录下新建settings.json文件&#xff0c;并将待传底的参数写在 cmake.debugConfig里。 下面介绍了一个示例&a…

重磅!2014-2023七大顶刊中国学者排行榜出炉,施一公、颜宁位列前二

在科学领域&#xff0c;Cell、Nature和Science被公认为最顶尖的期刊&#xff0c;简称CNS。而在医学方面&#xff0c;新英格兰医学杂志(NEJM)、柳叶刀(Lancet)、美国医学会杂志(JAMA)以及英国医学期刊(BMJ)被誉为“四大医学顶刊”。这七大期刊上发表的论文&#xff0c;往往被看作…

平台工程:构建企业数字化转型的基石

有人说&#xff0c;平台工程&#xff08;Platform Engineering&#xff09;&#xff0c;不过是新瓶装旧酒&#xff08;DevOps&#xff09;。 而Gartner 将平台工程列为 2024 顶级战略技术趋势之一。我国信通院也开始陆续制定与平台工程相关的技术标准。 随着数字化浪潮的席卷…

2024年软考计划开始了,你准备好了吗?

目录标题 2024年度计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试工作计划计算机软考中级科目哪个含金量最高&#xff1f;报考流程和说明 2024年度计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试工作计划 一、2024年度计算机软件资格考试(初级…

数学建模-多目标规划算法(美赛建模)

单目标优化的情况下&#xff0c;只有一个目标&#xff0c;任何两解都可以依据单一目标比较其好坏&#xff0c;可以得出没有争议的最优解。 多目标化与传统的单目标优化相对。多目标优化的概念是在某个情景中在需要达到多个目标时&#xff0c;由于容易存在目标间的内在冲突&…

MO干货 | shuffle执行计划解析(下篇)

作者&#xff1a;倪涛 MO产品布道师 目录 Part 1.如何处理不均匀数据&#xff1f; Part 2.Hybrid shuffle Part 3.Shuffle resue Part 4.Join reorder Part 5.总结 在《MO干货&#xff5c;shuffle执行计划解析&#xff08;上篇&#xff09;》中&#xff0c;我们分享了shu…

选课模块-01添加免费/收费选课

添加选课 界面原型 第一步&#xff1a;用户通过搜索课程、课程推荐等信息进入课程详情页面&#xff0c;点击马上学习进行学习 第二步&#xff1a;课程免费时可以直接加入我的课程表并且免费课程可以直接在线学习&#xff0c;免费课程默认一年有效期&#xff0c;到期需要申请续…

148个Chatgpt关键词汇总-有爱AI实战教程(二)

演示站点&#xff1a; https://ai.uaai.cn 技能模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 导读&#xff1a;在使用 ChatGPT 时&#xff0c;当你给的指令越精确&#xff0c;它的回答会越到位&#xff0c;举例来说&#xff0c;假如你要请它帮忙写文案&#xff0c;如…

C语言经典算法学习-4

文章目录 21.最大访客数22.中序式转后序式&#xff08;前序式&#xff09;23.后序式的运算24.洗扑克牌&#xff08;乱数排列&#xff09;25.Craps赌博游戏 21.最大访客数 说明&#xff1a;现将举行一个餐会&#xff0c;让访客事先填写到达时间与离开时间&#xff0c;为了掌握座…

2024年Vue3 面试题小总结

Vue3 面试题小总结 1. OptionsAPI 与 CompositionAPI 的区别&#xff1f; OptionsAPI&#xff1a; 选项式API&#xff0c;通过定义data、computed、watch、method等属性与方法&#xff0c;共同处理页面逻辑&#xff1b;缺点&#xff1a; 当组件变得复杂的时候&#xff0c;导致…

视频分割软件,到底哪一款才适合你?

在当今充满创意的数字时代&#xff0c;视频编辑已成为许多人表达想法、分享故事的重要手段。而在视频编辑的过程中&#xff0c;分割视频是一项关键而常见的任务&#xff0c;它能够让我们更精细地处理内容&#xff0c;使得最终的作品更为生动和引人入胜。然而&#xff0c;要想高…

揭秘财务数据分析的五力分析,轻松实现从会计财务到管理财务的华丽转身

在这个信息爆炸的时代&#xff0c;财务数据分析已经成为了企业和个人成功的关键。今天&#xff0c;就让我们一起揭开财务数据分析的神秘面纱&#xff0c;让你轻松掌握财务秘籍&#xff0c;成为财务高手&#xff01; 一、财务数据分析&#xff0c;为何如此重要&#xff1f; 财…

访客到了官网就跳走,概率是官网颜值和体验出了问题。

很多小伙伴反馈官网ip不错&#xff0c;但是pv太少了&#xff0c;停留时间更少&#xff0c;这大概率是网站颜值和体验出问题了。 如果访客到了官网后就跳走&#xff0c;有可能是因为官网的颜值和用户体验出了问题。这种情况可能会导致访客对网站的第一印象不佳&#xff0c;从而选…

【spring】使用阿里Spring Initailiz创建项目

网络原因使用Spring Initailiz会出现超时。 那我们就换成阿里的 先看看spring官网的 网址&#xff1a;https://start.spring.io 使用一下阿里的 网址&#xff1a;https://start.aliyun.com/ 填写信息 都是java开发者&#xff0c;具体信息部介绍了。 选择组件 lombok spri…

OKHttpRetrofit

完成一个get请求 1.导入依赖 implementation("com.squareup.okhttp3:okhttp:3.14.")2.开启viewBinding android.buildFeatures.viewBinding true 3.加网络权限 和 http明文请求允许配置文件 <?xml version"1.0" encoding"utf-8"?> &l…

Kotlin:内联类(inline class)

点击查询内联类中文文档 点击查询内联类英文文档 简介 提醒&#xff1a;内联类仅在 Kotlin 1.3 之后版本可用 有时候&#xff0c;业务逻辑需要围绕某种类型创建包装器。然而&#xff0c;由于额外的堆内存分配问题&#xff0c;它会引入运行时的性能开销。此外&#xff0c;如果…

【嵌入式——QT】标准对话框

【嵌入式——QT】标准对话框 文件对话框颜色对话框字体对话框输入对话框消息框代码示例 文件对话框 QFileDialog 常用静态函数 getOpenFileName&#xff1a;选择打开一个文件&#xff1b;getOpenFileNames&#xff1a;选择打开多个文件&#xff1b;getSaveFileName&#xff1…
最新文章