• springboot项目的文件上传至本地的minio框架


    文件上传,可以上传至本地,也可以上传至第三方服务器(阿里云,七牛云等)上,这篇文件是讲上传至本地的做法。

    一、minIO简介

    官网:https://min.io/
    操作文档:https://docs.min.io/docs/java-client-quickstart-guide.html
    中文版:http://www.minio.org.cn/ (注意:中文版本的有些资料更新没那么及时,建议看官网地址)
    github项目地址:https://github.com/minio/
    下载地址:https://min.io/download
    511689

    MinIO 是一款基于Go语言的高性能对象存储服务。它采用了Apache License v2.0开源协议,兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。

    二、安装minIO

    MInIO的安装有很多方法、单实例的、集群分布式的、docker部署的、支持k8s的,我们使用最简单的一种安装方式:linux单节点安装。

    如果希望对MinIO有深入的掌握,访问MinIO官网:https://min.io

    2.1 微软Windows系统

    下载二进制文件 : 微软Windows系统 64位 https://dl.min.io/server/minio/release/windows-amd64/minio.exe

    然后输入命令:
    minio.exe server D:\Photos

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    输入http://127.0.0.1:9000输入账号密码
    在这里插入图片描述

    2.2 GNU/Linux 安装

    方式一:

    下载二进制文件 :GNU/Linux 64-bit Intel https://dl.min.io/server/minio/release/linux-amd64/minio

    Copychmod +x minio./minio server /data

    方式二:推荐
    首先在/root目录下创建一个minio文件夹

    cd /root
    mkdir minio
    cd minio
    wget https://dl.min.io/server/minio/release/linux-amd64/minio
     
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    等待下载完成后:

    在当前minio目录下,会出现一个minio目录

    chmod +x minio
     
    # 创建minio文件存储目录及日志目录
    mkdir -p /root/data/minio;
    mkdir -p /root/logs/minio;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后在 /root/minio/目录下,新建一个run.sh并编辑以下内容

    vim run.sh,然后将以下内容保存到run.sh,并为其赋予执行权限chmod u+x run.sh

    #!/bin/bash
    export MINIO_ROOT_USER=fsp-manage
    export MINIO_ROOT_PASSWORD=springboot-fsp-manage
    # nohup启动服务 指定文件存放路径 /root/data 还有设置日志文件路径 /root/minio/log
    nohup ./minio server --address :9002 --console-address :9001 /root/data/minio > /root/logs/minio/minio.log 2>&1 &
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:以前的老版本minio的配置中,配置用户名和密码时,是这两个参数:

    MINIO_ACCESS_KEY 和MINIO_SECRET_KEY

    而现在比较新的版本的minio,需要替换成MINIO_ROOT_USER和MINIO_ROOT_PASSWORD

    并且用户名和密码都是由长度限制的,用户名长度不能小于3,密码不能小于8个字符

    –address :9002 --console-address :9001 是配置端口,默认minio端口是9000,如果9000端口被占用了,那就加上这一串配置,端口号的冒号之前不需要特意写出ip,当然如果你的ip的动态变化的,而不是静态的话,前边的ip不用写上,当然最好是用静态的ip

    然后启动minio

    # 启动minio服务
    bash run.sh
    # 查看日志
    tail -200f /root/logs/minio/minio.log
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    然后会有日志打印信息,然后可以看到minio服务器地址,和控制台信息地址

    然后在浏览器中访问地址

    http://192.168.0.131:9002,输入这个地址后会重定向到控制台登录地址http://192.168.0.131:9001/login

    然后在登录界面输入用户名和密码即可登录

    然后登录后进入首页,创建一个bucket

    在这里插入图片描述

    在这里插入图片描述

    然后打开可预览的设置

    在这里插入图片描述

    接下来我以开发环境中的桶演示minio文件的上传和下载等

    2.3 Docker 容器

    Copydocker pull minio/minio
    docker run -p 9000:9000 minio/minio server /data

    安装后使用浏览器访问http://127.0.0.1:9000,如果可以访问,则表示minio已经安装成功。

    三、使用

    3.1 导入依赖

    查找 minio 最新依赖,通过 maven 查询网站查询, 这搜索框输入 minio, 也可以查看 MinIO 官网 https://docs.min.io/docs/java-client-quickstart-guide.html如下

    在这里插入图片描述

    
            
                io.minio
                minio
                8.3.4
            
    
    
                me.tongfei
                progressbar
                0.5.3
            
    
            
                com.squareup.okhttp3
                okhttp
                4.8.1
            
    
     
                org.projectlombok
                lombok
            
    
    
                com.alibaba
                fastjson
                1.2.83
            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    3.2 pom

    
    server:
      port: 9002
    
    
    spring:
      servlet:
        multipart:
          enabled: true # 开启文件上传
          max-file-size: 10MB #限制文件上传大小
    	  max-request-size: 100MB
    
    
    
    # 自定义minio 参数配置	  
    minio:
      endpoint: http://localhost:9000 # MinIO服务所在地址和端口号
      accessKey: minioadmin # 访问的key
      secretKey:minioadmin # 访问的秘钥
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.3 minio配置类

    方式一:

    @Configuration
    public class MinIoClientConfig {
     
        @Value("${minio.endpoint}")
        private String endpoint;
        @Value("${minio.accessKey}")
        private String accessKey;
        @Value("${minio.secretKey}")
        private String secretKey;
     
        /**
         * 注入minio 客户端
         * @return
         */
        @Bean
        public MinioClient minioClient(){
     
        return MinioClient.builder()
                            .endpoint(endpoint)
                            .credentials(accessKey, secretKey)
                            .build();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    方式二:

    package com.xiaomifeng1010.minio.configuration;
     
    import io.minio.MinioClient;
    import io.minio.errors.InvalidPortException;
    import lombok.Getter;
    import lombok.Setter;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Component;
     
    /**
     * @author xiaomifeng1010
     * @version 1.0
     * @date: 2022/5/20 10:30
     * @Description minio配置
     */
    @Configuration
    @Component
    @ConfigurationProperties(prefix = "minio")
    @Getter
    @Setter
    public class MinioConfig {
        private String endpoint;
        private String accessKey;
        private String secretKey;
    
     
        @Bean
        public MinioClient getMinioClient() throws InvalidPortException {
            MinioClient minioClient = MinioClient.builder().endpoint(endpoint)
                    .credentials(accessKey, secretKey)
                    .build();
            return minioClient;
        }
    //
    //    @Bean(name = "multipartResolver")
    //    public MultipartResolver multipartResolver(){
    //        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
    //        resolver.setDefaultEncoding("UTF-8");
    //        //resolveLazily属性启用是为了推迟文件解析,以在在UploadAction中捕获文件大小异常
    //        resolver.setResolveLazily(true);
    //        resolver.setMaxInMemorySize(40960);
    //        //上传文件大小 50M 50*1024*1024
    //        resolver.setMaxUploadSize(50*1024*1024);
    //        return resolver;
    //    }
    }
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    3.4 使用

    package com.example.demo001.controller;
    
    import io.minio.GetObjectArgs;
    import io.minio.GetObjectResponse;
    import io.minio.MinioClient;
    import io.minio.PutObjectArgs;
    import org.springframework.util.FastByteArrayOutputStream;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.annotation.Resource;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @author lc
     * @version 1.0
     * @date 2022/8/4 13:30
     */
    @RestController
    public class UploadController {
    
        @Resource
        private MinioClient minioClient;
    
        /**
         * 文件上传
         * @param file
         * @return
         */
        @PostMapping("/upload")
        public String upload(MultipartFile file){
            try {
                PutObjectArgs objectArgs = PutObjectArgs.builder().object(file.getOriginalFilename())
                        .bucket("test") // 桶名字
                        .contentType(file.getContentType())
                        .stream(file.getInputStream(),file.getSize(),-1).build();
    
                minioClient.putObject(objectArgs);
                return "ok";
            } catch (Exception e) {
                e.printStackTrace();
                return e.getMessage();
            }
        }
    
    
        /**
         * 下载文件
         * @param filename
         */
        @GetMapping("/download/{filename}")
        public void download(@PathVariable String filename, HttpServletResponse res){
    
            GetObjectArgs objectArgs = GetObjectArgs.builder().bucket("test")
                    .object(filename).build();
    
            try (GetObjectResponse response = minioClient.getObject(objectArgs)){
                byte[] buf = new byte[1024];
    
                int len;
    
                try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){
    
                    while ((len=response.read(buf))!=-1){
    
                        os.write(buf,0,len);
    
                    }
                    os.flush();
    
                    byte[] bytes = os.toByteArray();
    
                    res.setCharacterEncoding("utf-8");
                    res.setContentType("application/force-download");// 设置强制下载不打开
                    res.addHeader("Content-Disposition", "attachment;fileName=" + filename);
                    try ( ServletOutputStream stream = res.getOutputStream()){
                        stream.write(bytes);
                        stream.flush();
                    }
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    上传接口调用
    在这里插入图片描述

    如何通过浏览器访问刚上传的图片呢,就是通过 endpoint 服务地址加 bucket 名称加图片的名称,在本例子访问路径则为:29d6d5c639b72e82cdad274396b9bc02.jpeg

    下载接口调用

    在这里插入图片描述

    启动SpringBoot应用,使用Postman来访问上传接口进行文件上传

    上传完成后,我们打开MinIO的管理界面可以看到上传后的图片,也可以通过返回的url来访问图片:

    四、扩展

    4.1 重复文件的校验

    4.2 分布式文件存储

  • 相关阅读:
    生物标志物发现中的无偏数据分析策略
    Android . java中解析json数据中文变成问号
    【JDK 8-函数式编程】4.6 方法引用与构造函数引用
    Redis性能调优:深度剖析与示例解析
    gorm的简单操作
    Polygon zkEVM 基本概念
    ImageNet classification with deep convolutional neural networks
    高通导航器软件开发包使用指南(17)
    AWS SAA-C03 #38
    TortoiseSVN 详细操作指南
  • 原文地址:https://blog.csdn.net/LC_Liangchao/article/details/126154803