Bootstrap

Spring Boot 3 整合 minio 实现文件存储

SpringBoot 整合 minio 实现文件存储

01、背景介绍

在软件系统的实际开发进程里,文件存储服务的使用常常是难以避免的。

就拿小型网站系统来说,一般情况下,会把文件存储服务和网站系统部署在同一台服务器上。这种做法在小成本资源投入方面确实具有一定优势。如果网站的访问量处于较低水平,这种方式基本不会引发什么问题。然而,随着网站访问量的逐步攀升,网站文件资源的读取操作变得越来越频繁。此时,单台服务器可能就无法承受如此大量的请求了,进而导致网站打不开或者出现系统异常等情况。

MinIO,作为一款被宣称是世界上速度最快的对象存储服务器,主要为大规模的数据存储和分析而精心打造。它具有很强的适应性,能够在多种环境下进行部署,像物理服务器、虚拟机、容器等都不在话下。更为重要的是,MinIO的技术文档十分完备,这就意味着使用者可以轻松上手。而且,对于个人用户而言,它完全是开源免费的。

今天这篇文章就将带大家一同探索如何运用MinIO搭建一套专属的云存储服务。

2、方案实践

2.1、minio 快速安装

以 windows 操作系统为例,安装请参考《Windows下Minio的安装以及基本使用》。

2.2.3、设置文件公开访问

默认创建的存储桶,都是私有桶,也就是说无法被公开访问。

image-20250109223939051

3、springBoot 集成 minio 实现文件存储

我们一起来看看,如何在 Spring Boot 工程中集成 minio 客户端以便实现文件存储服务。

3.1、创建用户访问密钥

MinIO 支持通过用户、密码来管理存储桶,我们可以利用 minio 客户端来实现文件的上传和下载。点击Access Keys菜单,创建用户名和密码并将其保存,下文会用到。image-20250109224308667

3.2、引入依赖包

在 Spring Boot 工程,引入 minio 客户端依赖包。我们可以去官网看找到最新的依赖。

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.5.10</version>
</dependency>
3.3、添加相关配置

在application.properties文件中,添加 minio 相关的配置信息.

minio.endpoint=http://127.0.0.1:9090
# 使用账号密码
#minio.access-key=minioadmin
#minio.secret-key=password

# 使用密钥
minio.access-key=eFbF9rSBtgfqiLGDcPDo
minio.secret-key=Sfgc06T1S6zhzVTzCwIFhr6KUs7zqCwOwFkHHez4
minio.bucket-name=harry

API: http://127.0.0.1:9090
RootUser: minioadmin
RootPass: password

注意下这里,因为我们配置的端口是9090,所以这里是9090而不是9000,要不会出现io.minio.errors.InvalidResponseException: Non-XML response from server. Response code: 400, Content-Type: text/xml;...... 异常信息

3.4、编写 Minio 客户端配置类

基于上文的配置信息,编写 Minio 客户端配置类。

@Configuration
public class MinioConfig {

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

    @Value("${minio.access-key}")
    private String minioAccessKey;

    @Value("${minio.secret-key}")
    private String minioSecretKey;

    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint(minioEndpoint)
                .credentials(minioAccessKey, minioSecretKey)
                .build();
    }
}
3.5、编写上传和文件预览服务

接着利用 minioClient 客户端,编写上传和文件预览服务。

/**
 * @author harry
 * @公众号 Harry技术
 */
@RestController
public class FileController {
    @Value("${minio.bucket-name}")
    private String bucketName;

    @Autowired
    private MinioClient minioClient;

    /**
     * 文件上传
     */
    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) {

        // 生成文件名(日期文件夹)
        String suffix = FileUtil.getSuffix(file.getOriginalFilename());
        String uuid = IdUtil.simpleUUID();
        String fileName = DateUtil.format(LocalDateTime.now(), "yyyyMMdd") + "/" + uuid + "." + suffix;
        //  try-with-resource 语法糖自动释放流
        try (InputStream inputStream = file.getInputStream()) {
            // 文件上传
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .contentType(file.getContentType())
                    .stream(inputStream, inputStream.available(), -1)
                    .build();
            minioClient.putObject(putObjectArgs);

            // 返回文件路径
            String fileUrl;
            GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs.builder()
                    .bucket(bucketName).object(fileName)
                    .method(Method.GET)
                    .build();

            fileUrl = minioClient.getPresignedObjectUrl(getPresignedObjectUrlArgs);
            fileUrl = fileUrl.substring(0, fileUrl.indexOf("?"));
            return fileUrl;
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }
}

3.6、使用Apifox上传

image-20250109224529107

返回图片地址:http://127.0.0.1:9090/harry/20250109/0fd3f0df56674ede8be935951d3170cf.png

curl --location --request POST ‘http://127.0.0.1:8080/upload’ \

–header ‘User-Agent: Apifox/1.0.0 (https://apifox.com)’ \

–header ‘Accept: /’ \

–header ‘Host: 127.0.0.1:8080’ \

–header ‘Connection: keep-alive’ \

–header ‘Content-Type: multipart/form-data; boundary=--------------------------602606623533285111744711’ \

–form ‘file=@“C:\Users\Admin\Downloads\微信截图_20250106132845.png”’

3.7、验证

回到 minio 控制台,可以看到刚刚上传的文件信息。

image-20250109224739696

2)文件预览地址验证

在浏览器端,访问http://127.0.0.1:9090/harry/20250109/0fd3f0df56674ede8be935951d3170cf.png预览地址,可以清晰的看到图片能正常展示。

总结

到这里,我们已经掌握了springBoot 整合 minio 实现文件存储的过程。

示例源码:关注公众号“Harry技术”,回复 minio 获取源码地址。

;