Spring Boot配置MinIO(实现文件上传、读取、下载、删除)

一、 MinIO

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

MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。

二、 MinIO安装和启动

由于MinIO是一个单独的服务器,需要单独部署,有关MinIO在Windows系统上的使用请查看以下博客。

Windows MinIO使用教程(启动,登录,修改密码):https://blog.csdn.net/Angel_asp/article/details/128544612

三、 pom.xml(maven依赖文件)

<dependency>    <groupId>org.projectlombok</groupId>    <artifactId>lombok</artifactId>    <version>1.18.16</version></dependency><!-- SpringBoot Web容器 --><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId></dependency><dependency>    <groupId>io.minio</groupId>    <artifactId>minio</artifactId>    <version>8.3.4</version></dependency>

四、 applicatin.properties(配置文件)

# 设置单个文件大小spring.servlet.multipart.max-file-size= 50MB#minio文件服务器配置s3.url=http://localhost:9000s3.accessKey=admins3.secretKey=admin123s3.bucketName=test

五、 编写Java业务类

minio涉及到的方法有:判断存储桶是否存在,创建存储桶,上传文件,读取文件、下载文件,删除文件等操作

1、StorageProperty 存储属性类:

import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;/** * @Author yang * @Date 2023/1/3 14:00 * @Version 1.0 */@Data@Component@ConfigurationProperties(prefix = "s3")public class StorageProperty {    private String url;    private String accessKey;    private String secretKey;//    private long callTimeOut = 60000;//    private long readTimeOut = 300000;}

2、minio 配置类:

import io.minio.BucketExistsArgs;import io.minio.MinioClient;import io.minio.messages.Bucket;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;import java.util.List;
/** * @Author yang * @Date 2023/1/3 14:03 * @Version 1.0 */@Slf4j@Component@Configurationpublic class MinioClientConfig {    @Autowired    private StorageProperty storageProperty;
    private static MinioClient minioClient;     /**     * @description: 获取minioClient     * @date 2021/6/22 16:55     * @return io.minio.MinioClient     */    public static MinioClient getMinioClient(){        return minioClient;    }
    /**     * 判断 bucket是否存在     *     * @param bucketName:     *            桶名     * @return: boolean     * @date : 2020/8/16 20:53     */    @SneakyThrows(Exception.class)    public static boolean bucketExists(String bucketName) {        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());    }     /**     * 获取全部bucket     *     * @param :     * @return: java.util.List<io.minio.messages.Bucket>     * @date : 2020/8/16 23:28     */    @SneakyThrows(Exception.class)    public static List<Bucket> getAllBuckets() {        return minioClient.listBuckets();    }
    /**     * 初始化minio配置     *     * @param :     * @return: void     * @date : 2020/8/16 20:56     */    @PostConstruct    public void init() {        try {            minioClient = MinioClient.builder()                    .endpoint(storageProperty.getUrl())                    .credentials(storageProperty.getAccessKey(), storageProperty.getSecretKey())                    .build();        } catch (Exception e) {            e.printStackTrace();            log.error("初始化minio配置异常: 【{}】", e.fillInStackTrace());        }    }
}

3、minio工具类

import io.minio.*;
import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletResponse;import java.io.InputStream;import java.nio.charset.StandardCharsets;import java.util.Map;
/** * @Author yang * @Date 2023/1/3 14:15 * @Version 1.0 */@Slf4j@Componentpublic class MinioUtil {     /**     * Minio文件上传     *     * @param file       文件实体     * @param fileName   修饰过的文件名 非源文件名     * @param bucketName 所存文件夹(桶名)     * @return     */    public ResultEntity<Map<String, Object>> minioUpload(MultipartFile file, String fileName, String bucketName) {        ResultEntity<Map<String, Object>> resultEntity = new ResultEntity();        try {            MinioClient minioClient = MinioClientConfig.getMinioClient();            // fileName为空,说明要使用源文件名上传            if (fileName == null) {                fileName = file.getOriginalFilename();                fileName = fileName.replaceAll(" ", "_");            }            InputStream inputStream = file.getInputStream();            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName)                    .stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build();            //文件名称相同会覆盖            minioClient.putObject(objectArgs);            return resultEntity;        } catch (Exception e) {            e.printStackTrace();            return null;        }    }
    /**     * 检查存储桶是否存在     *     * @param bucketName 存储桶名称     * @return     */    public boolean bucketExists(String bucketName) {        boolean flag = false;        try {            flag = MinioClientConfig.bucketExists(bucketName);            if (flag) {                return true;            }        } catch (Exception e) {            e.printStackTrace();            return false;        }        return false;    }
    /**     * 获取文件流     *     * @param fileName   文件名     * @param bucketName 桶名(文件夹)     * @return     */    public InputStream getFileInputStream(String fileName, String bucketName) {        try {            MinioClient minioClient = MinioClientConfig.getMinioClient();            return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());        } catch (Exception e) {            e.printStackTrace();            log.error(e.getMessage());        }        return null;    }     /**     * @param bucketName:     * @author     * @description: 创建桶     * @date 2022/8/16 14:36     */    public void createBucketName(String bucketName) {        try {            if (StringUtils.isBlank(bucketName)) {                return;            }            MinioClient minioClient = MinioClientConfig.getMinioClient();            boolean isExist = MinioClientConfig.bucketExists(bucketName);            if (isExist) {                log.info("Bucket {} already exists.", bucketName);            } else {                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());            }        } catch (Exception e) {            e.printStackTrace();            log.error(e.getMessage());        }    }    /**     * 下载文件     *     * @param originalName 文件路径     */    public InputStream downloadFile(String bucketName, String originalName, HttpServletResponse response) {        try {            MinioClient minioClient = MinioClientConfig.getMinioClient();            InputStream file = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(originalName).build());            String filename = new String(originalName.getBytes("ISO8859-1"), StandardCharsets.UTF_8);            if (StringUtils.isNotBlank(originalName)) {                filename = originalName;            }            response.setHeader("Content-Disposition", "attachment;filename=" + filename);            ServletOutputStream servletOutputStream = response.getOutputStream();            int len;            byte[] buffer = new byte[1024];            while ((len = file.read(buffer)) > 0) {                servletOutputStream.write(buffer, 0, len);            }            servletOutputStream.flush();            file.close();            servletOutputStream.close();            return file;        } catch (Exception e) {            e.printStackTrace();            return null;        }    }
    /**     * @param bucketName:     * @description: 删除桶     * @date 2022/8/16 14:36     */    public void deleteBucketName(String bucketName) {        try {            if (StringUtils.isBlank(bucketName)) {                return;            }            MinioClient minioClient = MinioClientConfig.getMinioClient();            boolean isExist = MinioClientConfig.bucketExists(bucketName);            if (isExist) {                minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());            }        } catch (Exception e) {            e.printStackTrace();            log.error(e.getMessage());        }    }    /**     * @param bucketName:     * @description: 删除桶下面所有文件     * @date 2022/8/16 14:36     */    public void deleteBucketFile(String bucketName) {        try {            if (StringUtils.isBlank(bucketName)) {                return;            }            MinioClient minioClient = MinioClientConfig.getMinioClient();            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());            if (isExist) {                minioClient.deleteBucketEncryption(DeleteBucketEncryptionArgs.builder().bucket(bucketName).build());            }        } catch (Exception e) {            e.printStackTrace();            log.error(e.getMessage());        }    }
    /**     * 根据文件路径得到预览文件绝对地址     *     * @param bucketName     * @param fileName     * @return     */    public String getPreviewFileUrl(String bucketName, String fileName) {        try {            MinioClient minioClient = MinioClientConfig.getMinioClient();            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).build());        } catch (Exception e) {            e.printStackTrace();            return "";        }    }}

六、 MinIoController

文件上传、文件读取、文件下载、文件删除接口如下:

/** * @Author yangb * @Date 2022/11/27 15:55 * @Version 1.0 */@RestController@RequestMapping("/minio")public class MinIoController extends BaseController {
    MinioUtil minioUtil = new MinioUtil();
    /**     * 上传文件     * @param file     * @return     */    @PostMapping("/uploadFile")    public AjaxResult uploadFile(@RequestBody MultipartFile file) {        MinioClient minioClient = MinioClientConfig.getMinioClient();        if (minioClient == null) {            return AjaxResult.error("连接MinIO服务器失败", null);        }        ResultEntity<Map<String, Object>> result = minioUtil.minioUpload(file, "", "data-enpower");        if (result.getCode() == 0) {            return AjaxResult.success("上传成功");        } else {            return AjaxResult.error("上传错误!!!");        }    }
    /**     * 获取文件预览地址     * @param fileName     * @return     */    @RequestMapping("/getRedFile")    public AjaxResult getRedFile(@RequestBody String fileName) {        MinioClient minioClient = MinioClientConfig.getMinioClient();        if (minioClient == null) {            return AjaxResult.error("连接MinIO服务器失败", null);        }        String url = minioUtil.getPreviewFileUrl("data-enpower",fileName);        return AjaxResult.success(url);    }
    /**     * 下载文件     * @param fileName     * @param response     * @return     */    @RequestMapping("/downloadFile")    public String downloadFile(@RequestParam String fileName, HttpServletResponse response) {        MinioClient minioClient = MinioClientConfig.getMinioClient();        if (minioClient == null) {            return "连接MinIO服务器失败";        }        return minioUtil.downloadFile("data-enpower",fileName,response) != null ? "下载成功" : "下载失败";    }
    /**     * 删除文件     *     * @param fileName 文件路径     * @return     */    @PostMapping("/deleteFile")    public String deleteFile(String fileName) {        MinioClient minioClient = MinioClientConfig.getMinioClient();        if (minioClient == null) {            return "连接MinIO服务器失败";        }        boolean flag = minioUtil.deleteFile("data-enpower",fileName);        return flag == true ? "删除成功" : "删除失败";    }
}

七、调试结果

1、文件上传

图片

minio上的文件:

图片

2、文件下载 

图片

3、文件删除 

图片

我们在minio上看看文件是否已删除

图片

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

奔跑吧茂林小子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值