您现在的位置是:首页 > 正文

springboot整合minio上传文件

2024-02-01 00:15:11阅读 2

1.安装minio

这里采用docker进行安装。

搜索该镜像:docker search minio

找到了镜像:minio/minio

拉取镜像:docker pull minio/minio

启动镜像:

docker run --name minio -p 9090:9000 -p 9999:9999 -d \
--restart=always -e \
"MINIO_ROOT_USER=minioadmin" \
-e "MINIO_ROOT_PASSWORD=minioadmin123?" \
-v /home/minio/data:/data \
-v /home/minio/config:/root/.minio minio/minio server /data --console-address '0.0.0.0:9999'
 

浏览器访问minio的控制台:

http://ip:port

访问到网页如下: 

2.配置minio

1.创建一个放图片的目录

登录网页进去:

点击左侧Buckets页面,然后点击右边的 Create Bucket 去创建一个目录,这个目录,如下,我创建了一个imgs,这个目录用来放上传的图片,需要记住这个目录,代码里面需要用

 

2.创建上传文件需要的key

 需要把这两个key复制出来,代码里面需要用,就相当于账户密码之类的

3.springboot整合minio

1. 导入maven

        <!--minio-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.2.1</version>
        </dependency>

2.配置yml文件

# minio文件系统配置
minio:
  # minio配置的地址,端口9090
  url: http://xxx.xx.xx.xx:9090
  # 账号
  accessKey: RKGZKAUGHKDY0XVN
  # 密码
  secretKey: HmTlAJoll7V0OjfBoyKmsIGF
  # MinIO桶名字
  bucketName: imgs

3.代码部分

MinioUtil.java
package com.tn.humanenv.common.utils;

import io.minio.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;

/**
 * minio存储
 */
@Component
public class MinioUtil {
    
    @Autowired
    private MinioClient minioClient;


    /**
     * @author xhw
     * @生成文件名
     * @param fileName
     * @return
     */
    public String getUUIDFileName(String fileName) {
        int idx = fileName.lastIndexOf(".");
        String extention = fileName.substring(idx);
        String newFileName = DateUtils.getDateTo_().replace("-","")+UUID.randomUUID().toString().replace("-","")+extention;
        return newFileName;
    }



    /**
     * 查看存储bucket是否存在
     *
     * @param bucketName 存储bucket
     * @return boolean
     */
    public Boolean bucketExists(String bucketName) {
        Boolean found;
        try {
            found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return found;
    }

    /**
     * 创建存储bucket
     *
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 删除存储bucket
     *
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 文件上传
     *
     * @param file       文件
     * @param bucketName 存储bucket
     * @return Boolean
     */
    public Boolean upload(MultipartFile file, String fileName, String bucketName) {
        try {
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            //文件名称相同会覆盖
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 文件下载
     *
     * @param bucketName 存储bucket名称
     * @param fileName   文件名称
     * @param res        response
     * @return Boolean
     */
    public void download(String bucketName, String fileName, HttpServletResponse res) {
        GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName)
                .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();
        }
    }

    /**
     * 查看文件对象
     *
     * @param bucketName 存储bucket名称
     * @return 存储bucket内文件对象信息
     */
/*    public List<ObjectItem> listObjects(String bucketName) {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        List<ObjectItem> objectItems = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                Item item = result.get();
                ObjectItem objectItem = new ObjectItem();
                objectItem.setObjectName(item.objectName());
                objectItem.setSize(item.size());
                objectItems.add(objectItem);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return objectItems;
    }*/

    /**
     * 批量删除文件对象
     *
     * @param bucketName 存储bucket名称
     * @param objects    对象名称集合
     */
    public Iterable<Result<DeleteError>> removeObjects(String bucketName, List<String> objects) {
        List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
        Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
        return results;
    }
}
SysFileController.java
package com.tn.humanenv.controller;

import com.tn.humanenv.common.controller.BaseController;
import com.tn.humanenv.common.domain.AjaxResult;
import com.tn.humanenv.common.utils.StringUtils;
import com.tn.humanenv.service.SysFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;

/**
 * @author xhw
 * @desc 文件上传
 * @date 2022/09/04
 */
@RestController
@RequestMapping("/file")
public class SysFileController extends BaseController {

    @Autowired
    private SysFileService sysFileService;

    /**
     * 图片上传minio
     *
     * @param file 图片文件
     * @return 返回
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public AjaxResult uploadFileMinio(MultipartFile file) {
        Map<String,Object> map = sysFileService.uploadFileMinio(file);
        if (StringUtils.isNotNull(map)) {
            return AjaxResult.success(map);
        }
        return error("上传失败");
    }

}

SysFileServiceImpl.java
package com.tn.humanenv.service.Impl;

import com.tn.humanenv.common.config.MinioConfig;
import com.tn.humanenv.common.utils.MinioUtil;
import com.tn.humanenv.service.SysFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

@Service
public class SysFileServiceImpl implements SysFileService {

    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioUtil minioUtil;

    @Override
    public Map<String,Object> uploadFileMinio(MultipartFile file) {
        boolean flag = false;
        if (file.isEmpty()) {
            throw new RuntimeException("文件不存在!");
        }
        // 判断存储桶是否存在
        if (!minioUtil.bucketExists(minioConfig.getBucketName())) {
            minioUtil.makeBucket(minioConfig.getBucketName());
        }
        // 生成文件名
        String newFileName = minioUtil.getUUIDFileName(file.getOriginalFilename());
        try {
            // 上传文件
            flag = minioUtil.upload(file, newFileName, minioConfig.getBucketName());
        } catch (Exception e) {
            return null;
        }
        // 判断是否上传成功,成功就返回url,不成功就返回null
        Map<String,Object> map = new HashMap<>();
        map.put("url",minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + newFileName);
        map.put("fileName",newFileName);
        if (flag){
            return map;
        }
        return null;
    }
}
SysFileService.java
package com.tn.humanenv.service;

import org.springframework.web.multipart.MultipartFile;

import java.util.Map;

public interface SysFileService {
    public Map<String,Object> uploadFileMinio(MultipartFile file);
}
MinioConfig.java
package com.tn.humanenv.common.config;

import io.minio.MinioClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    /**
     * 服务地址
     */
    public String url;

    /**
     * 用户名
     */
    public String accessKey;

    /**
     * 密码
     */
    public String secretKey;

    /**
     * 存储桶名称
     */
    public String bucketName;

    // "如果是true,则用的是https而不是http,默认值是true"
    public static Boolean secure = false;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getAccessKey() {
        return accessKey;
    }

    public void setAccessKey(String accessKey) {
        this.accessKey = accessKey;
    }

    public String getSecretKey() {
        return secretKey;
    }

    public void setSecretKey(String secretKey) {
        this.secretKey = secretKey;
    }

    public String getBucketName() {
        return bucketName;
    }

    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }

    public static Boolean getSecure() {
        return secure;
    }

    public static void setSecure(Boolean secure) {
        MinioConfig.secure = secure;
    }

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

4.测试上传图片

调用接口如下: 

 

把链接拿出来浏览器访问如下:

上传excel文件如下: 

访问该地址,直接就下载了这个excel文件:

 

如上。

 

网站文章

  • 2022年6月29日--使用C#迈出第一步--使用 C# 中的“if”、“else”和“else if”语句向代码添加决策逻辑

    C#

    2024-02-01 00:14:53
  • vue——filter过滤器

    vue——filter过滤器

    参数是10,显示是100效果如下:1、局部过滤器关键性代码2、全局过滤器附加:多个过滤器串联:{{ message | filterA | filterB }}说明:filterA被定义为接收单个参数的过滤器函数,表达式message的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数filterB,将filterA的结果传递到filterB中。...

    2024-02-01 00:14:46
  • C语言|深入浅出讲解int转换为float全过程(附2017年统考大题案例)

    C语言|深入浅出讲解int转换为float全过程(附2017年统考大题案例)

    int转换为float类型为什么会发生精度损失? 精度损失的详细过程究竟是什么样的? 什么样情况float会发生精度损失?没有弄懂2017年浮点数统考大题? 这一篇用2017年统考大题案例帮你更深的理解浮点数的存储规则。

    2024-02-01 00:14:15
  • [洛谷5464]缩小社交圈

    xx 转载于:https://www.cnblogs.com/lxzl/p/11233989.html

    2024-02-01 00:14:10
  • 交叉表查询(普通行列转换)

    问题:假设有张学生成绩表(tb)如下: 姓名 课程 分数 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 李四 物理 94 想变成(得到如下结果): 姓名 语文 数学 物理 ---- ---- ---- ---- 李四 74  84  94 张三 74  83  93 ------------------

    2024-02-01 00:14:05
  • WIN32 API实现edit文本框的printf()函数

    在进行WIN32 API使用文本框编程时,很多情况下需要输出调试信息,或是直接输出一些有用的信息。我们通常使用SetWindowText()函数实现,但是其中的内容无法格式化修改,所以一般还要使用wsprintf()函数进行预格式化,最后还需要发送EM_SCROLL消息使滚动条显示到最下方,这就显得非常繁琐,往往要重复使用多次,失去了效率。修改之前的代码往往是这样的:GetLocalTi...

    2024-02-01 00:13:33
  • V8 引擎中的 JavaScript 数组实现分析与性能优化

    数组是 JavaScript 语言的一项基本功能,几乎每 个 JavaScript 应用程序中都会大量应用数组。由于 V8 的源程序公开,其运行机制可以通过分析其源程 序来深入了解。通过分析 Java...

    2024-02-01 00:13:28
  • Mysql学习-DQL

    DQL、SQL、Mysql

    2024-02-01 00:13:21
  • Shader(着色)

    Shader(着色)

    Shader(着色)

    2024-02-01 00:12:52
  • Ajax请求数据四部曲 cors解决跨域问题

    Ajax请求数据四部曲 cors解决跨域问题

    2024-02-01 00:12:47