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"。

 

由于涉及到前后端交互,这里提供一个完整的Spring Boot和Vue.js的文件上传功能模块的代码示例。 1. 后端代码 在Spring Boot中,我们可以使用MultipartFile类处理文件上传。我们可以定义一个Controller来处理上传请求,并在该Controller中使用MultipartFile类来处理上传文件。以下是一个简文件上传Controller示例: ```java @RestController public class FileUploadController { @PostMapping("/upload") public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file) { try { // 处理文件上传逻辑 return ResponseEntity.ok().build(); } catch (Exception e) { // 处理异常情况 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } } ``` 2. 前端代码 在Vue.js中,我们可以使用Vue.js的Axios库来处理文件上传。Axios是一个基于Promise的HTTP客户端,可以在浏览器和Node.js中使用。以下是一个简文件上传Vue组件示例: ```vue <template> <div> <input type="file" @change="selectFile" /> <button @click="uploadFile">Upload</button> </div> </template> <script> import axios from "axios"; export default { data() { return { selectedFile: null, }; }, methods: { selectFile(event) { this.selectedFile = event.target.files[0]; }, uploadFile() { let formData = new FormData(); formData.append("file", this.selectedFile); axios .post("/upload", formData, { headers: { "Content-Type": "multipart/form-data", }, }) .then((response) => { console.log(response.data); }) .catch((error) => { console.log(error); }); }, }, }; </script> ``` 在这个组件中,我们使用了一个input元素来让用户选择要上传的文件,并使用了一个button元素来触发文件上传操作。在selectFile方法中,我们使用了HTML5的File API来获取用户选择的文件,并将其保存到selectedFile变量中。在uploadFile方法中,我们创建了一个FormData对象,并将selectedFile添加到其中,然后使用Axios库的post方法发送文件上传请求。在请求头中,我们指定了Content-Type为multipart/form-data。 以上就是一个完整的Spring Boot和Vue.js的文件上传功能模块的代码示例。需要注意的是,由于涉及到文件上传,需要特别注意文件大小、文件类型、文件重名等问题,以确保系统的安全性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烟雨平生9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值