锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. JAVA
  4. Spring Boot + MinIO 实现文件切片极速上传技术

Spring Boot + MinIO 实现文件切片极速上传技术

0
  • JAVA
  • 发布于 2024-08-09
  • 0 次阅读
黄健
黄健

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net

文章目录

    • 1. 引言
    • 2. 文件切片上传简介
    • 3. 技术选型
      • 3.1 Spring Boot
      • 3.2 MinIO
    • 4. 搭建 Spring Boot 项目
    • 5. 集成 MinIO
      • 5.1 配置 MinIO 连接信息
      • 5.2 MinIO 配置类
    • 6. 文件切片上传实现
      • 6.1 控制器层
      • 6.2 服务层
      • 6.3 文件切片上传逻辑
    • 7. 文件合并逻辑
    • 8. 页面展示
    • 9. 性能优化与拓展
      • 9.1 性能优化
      • 9.2 拓展功能
    • 10. 总结

🎉欢迎来到 SpringBoot 框架学习专栏~


  • ☆* o(≧▽≦)o *☆嗨~ 我是 IT· 陈寒🍹
  • ✨博客主页:IT· 陈寒的博客
  • 🎈该系列文章专栏:SpringBoot
  • 📜其他专栏:Java 学习路线 Java 面试技巧 Java 实战项目 AIGC 人工智能 数据结构学习
  • 🍹文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • 📜 欢迎大家关注! ❤️

1. 引言

在现代 Web 应用中,文件上传是一个常见的需求,尤其是对于大文件的上传,如视频、音频或大型文档。为了提高用户体验和系统性能,文件切片上传技术逐渐成为热门选择。本文将介绍如何使用 Spring Boot 和 MinIO 实现文件切片极速上传技术,通过将大文件分割成小片段并并行上传,显著提高文件上传速度。

2. 文件切片上传简介

文件切片上传是指将大文件分割成小的片段,然后通过多个请求并行上传这些片段,最终在服务器端将这些片段合并还原为完整的文件。这种方式有助于规避一些上传过程中的问题,如网络不稳定、上传中断等,并能提高上传速度。

3. 技术选型

3.1 Spring Boot

Spring Boot 是一个基于 Spring 框架的轻量级、快速开发的框架,提供了许多开箱即用的功能,适合构建现代化的 Java 应用。

3.2 MinIO

MinIO 是一款开源的对象存储服务器,与 Amazon S3 兼容。它提供了高性能、高可用性的存储服务,适用于大规模文件存储。

4. 搭建 Spring Boot 项目

首先,我们需要搭建一个基本的 Spring Boot 项目。可以使用 Spring Initializer(https://start.spring.io/)生成项目骨架,选择相应的依赖,如 Web 和 Thymeleaf。

<!-- pom.xml -->

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Thymeleaf模板引擎 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <!-- MinIO Java客户端 -->
    <dependency>
        <groupId>io.minio</groupId>
        <artifactId>minio</artifactId>
        <version>8.3.3</version>
    </dependency>
</dependencies>

5. 集成 MinIO

5.1 配置 MinIO 连接信息

在application.properties中配置 MinIO 的连接信息,包括服务地址、Access Key 和 Secret Key。

# application.properties

# MinIO配置
minio.endpoint=http://localhost:9000
minio.accessKey=minioadmin
minio.secretKey=minioadmin
minio.bucketName=mybucket

5.2 MinIO 配置类

创建 MinIO 配置类,用于初始化 MinIO 客户端。

import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MinioConfig {

    @Value("${minio.endpoint}")
    private String endpoint;

    @Value("${minio.accessKey}")
    private String accessKey;

    @Value("${minio.secretKey}")
    private String secretKey;

    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
    }
}

6. 文件切片上传实现

6.1 控制器层

创建一个文件上传的控制器,负责处理文件切片上传的请求。

import io.minio.MinioClient;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@RestController
@RequestMapping("/file")
public class FileController {

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucketName}")
    private String bucketName;

    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) {
        // 实现文件切片上传逻辑
        // ...

        return "Upload success!";
    }
}

6.2 服务层

创建文件上传服务类,处理文件切片的具体上传逻辑。

import io.minio.MinioClient;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@Service
public class FileService {

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucketName}")
    private String bucketName;

    public void uploadFile(String objectName, MultipartFile file) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, NoResponseException, ErrorResponseException, InternalException, InvalidBucketNameException, XmlParserException, InvalidArgumentException {
        // 实现文件切片上传逻辑
        // ...
    }
}

6.3 文件切片上传逻辑

在服务层的uploadFile方法中实现文件切片上传逻辑。这里使用 MinIO 的putObject方法将文件切片上传至 MinIO 服务器。

import io.minio.PutObjectArgs;
import io.minio.errors.*;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class FileService {

    // 省略其他代码...

    public void uploadFile(String objectName, MultipartFile file) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, NoResponseException, ErrorResponseException, InternalException, InvalidBucketNameException, XmlParserException, InvalidArgumentException {
        InputStream inputStream = file.getInputStream();
        long size = file.getSize();
        long chunkSize = 5 * 1024 * 1024; // 每片大小5MB

        long offset = 0;
        while (offset < size) {
            long currentChunkSize = Math.min(chunkSize, size - offset);
            byte[] chunk = new byte[(int) currentChunkSize];
            inputStream.read(chunk);

            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .stream(inputStream, currentChunkSize, -1)
                            .build()
            );

            offset += currentChunkSize;
        }

        inputStream.close();
    }
}

7. 文件合并逻辑

在文件上传完成后,需要将所有的切片文件合并还原为完整的文件。在FileController中增加一个合并文件的接口。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/file")
public class FileController {

    // 省略其他代码...

    @Autowired
    private FileService fileService;

    @PostMapping("/merge")
    public String merge(@RequestParam String objectName) {
        try {
            fileService.mergeFile(objectName);
            return "Merge success!";
        } catch (Exception e) {
            e.printStackTrace();
            return "Merge failed!";
        }
    }
}

在FileService中增加合并文件的方法。

import io.minio.CopyObjectArgs;
import io.minio.GetObjectArgs;
import io.minio.PutObjectArgs;
import io.minio.errors.*;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class FileService {

    // 省略其他代码...

    public void mergeFile(String objectName) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, NoResponseException, ErrorResponseException, InternalException, InvalidBucketNameException, XmlParserException, InvalidArgumentException {
        Iterable<io.minio.messages.Item> parts = minioClient.listObjects(bucketName, objectName);

        // 通过CopyObject将所有分片合并成一个对象
        for (io.minio.messages.Item part : parts) {
            String partName = part.objectName();
            minioClient.copyObject(
                    CopyObjectArgs.builder()
                            .source(bucketName, partName)
                            .destination(bucketName, objectName)
                            .build()
            );
        }

        // 删除所有分片
        for (io.minio.messages.Item part : parts) {
            String partName = part.objectName();
            minioClient.removeObject(bucketName, partName);
        }
    }
}

8. 页面展示

在前端页面,使用 Thymeleaf 模板引擎展示上传按钮和上传进度。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta >
    <title>File Upload</title>
</head>
<body>
    <form id="uploadForm" action="/file/upload" method="post" enctype="multipart/form-data">
        <input type="file"  />
        <input type="submit" value="Upload" />
    </form>

    <div id="progress" style="display: none;">
        <progress id="progressBar" max="100" value="0"></progress>
        <span id="percentage">0%</span>
    </div>

    <script>
        document.getElementById('uploadForm').addEventListener('submit', function (event) {
            event.preventDefault();

            var fileInput = document.getElementById('file');
            var file = fileInput.files[0];
            if (!file) {
                alert('Please choose a file.');
                return;
            }

            var formData = new FormData();
            formData.append('file', file);

            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/file/upload', true);

            xhr.upload.onprogress = function (e) {
                if (e.lengthComputable) {
                    var percentage = Math.round((e.loaded / e.total) * 100);
                    document.getElementById('progressBar').value = percentage;
                    document.getElementById('percentage').innerText = percentage + '%';
                }
            };

            xhr.onload = function () {
                document.getElementById('progress').style.display = 'none';
                alert('Upload success!');
            };

            xhr.onerror = function () {
                alert('Upload failed!');
            };

            xhr.send(formData);

            document.getElementById('progress').style.display = 'block';
        });
    </script>
</body>
</html>

9. 性能优化与拓展

9.1 性能优化

  • 并发上传: 利用多线程或异步任务,将文件切片并行上传,提高上传效率。
  • 分布式部署: 将文件存储和应用部署在不同的服务器,减轻单个服务器的负担,提高整体性能。

9.2 拓展功能

  • 断点续传: 支持文件上传中断后的断点续传功能,提高用户体验。
  • 权限控制: 使用 MinIO 的访问策略进行权限控制,确保文件上传安全性。

10. 总结

通过本文,我们深入了解了如何使用 Spring Boot 和 MinIO 实现文件切片上传技术。通过文件切片上传,我们能够提高文件上传的速度,优化用户体验。在实际应用中,我们可以根据需求进行性能优化和功能拓展,使得文件上传系统更加强大和可靠。希望本文对您理解文件切片上传技术以及 Spring Boot 和 MinIO 的使用有所帮助。

var code = "f3609a34-26b9-4f92-90de-d5d00ceee6e0"

🧸结尾 ❤️ 感谢您的支持和鼓励! 😊🙏
📜您可能感兴趣的内容:

  • 【Java 面试技巧】Java 面试八股文 - 掌握面试必备知识(目录篇)

  • 【Java 学习路线】2023 年完整版 Java 学习路线图

  • 【AIGC 人工智能】Chat GPT 是什么,初学者怎么使用 Chat GPT,需要注意些什么

  • 【Java 实战项目】SpringBoot+SSM 实战:打造高效便捷的企业级 Java 外卖订购系统

  • 【数据结构学习】从零起步:学习数据结构的完整路径

标签: #JAVA 991
相关文章

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

SpringBoot整合异步任务执行 2024-10-08 11:24

同步任务: 同步任务是在单线程中按顺序执行,每次只有一个任务在执行,不会引发线程安全和数据一致性等 并发问题 同步任务需要等待任务执行完成后才能执行下一个任务,无法同时处理多个任务,响应慢,影响用 户体验 异步任务: 异步任务是在多线程中同时执行,多个任务可以并发执行,同时处理多个请求,响应快,资源

springboot kafka多数据源,通过配置动态加载发送者和消费者 2024-10-08 11:24

前言 最近做项目,需要支持kafka多数据源,实际上我们也可以通过代码固定写死多套kafka集群逻辑,但是如果需要不修改代码扩展呢,因为kafka本身不处理额外逻辑,只是起到削峰,和数据的传递,那么就需要对架构做一定的设计了。 准备test kafka本身非常容易上手,如果我们需要单元测试,引入ja

SpringBoot 集成 Redis 2024-10-08 11:24

一:SpringBoot 集成 Redis ①Redis是一个 NoSQL(not only)数据库, 常作用缓存 Cache 使用。 ②Redis是一个中间件、是一个独立的服务器;常用的数据类型: string , hash ,set ,zset , list ③通过Redis客户端可以使用多种语

SpringBoot整合QQ邮箱 2024-10-08 11:24

SpringBoot可以通过导入依赖的方式集成多种技术,这当然少不了我们常用的邮箱,现在本章演示SpringBoot整合QQ邮箱发送邮件…. 下面按步骤进行: 1.获取QQ邮箱授权码 1.1 登录QQ邮箱 1.2 开启SMTP服务 找到下图中的SMTP服务区域,如果当前账号未开启的话自己手动开启。

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.