Minio整合springboot

1、pom依赖

<!-- minio 相关依赖 -->
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>7.1.0</version>
</dependency>
<dependency>
    <groupId>me.tongfei</groupId>
    <artifactId>progressbar</artifactId>
    <version>0.5.3</version>
</dependency>
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.8.1</version>
</dependency>

<!-- alibaba的fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.51</version>
</dependency>
<!-- thymeleaf模板引擎 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 开启configuration annotation processor -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

2、application.yml文件配置

minio:
  url: http://101.227.111.104:38000/
  accessKey: minioadmin
  secretKey: minioadmin
  bucketName: fund

3、实体类

``

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @author peiyuxiang
 * @date 2021/11/11
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {
    /**
     * minio地址+端口号
     */
    private String url;

    /**
     * minio用户名
     */
    private String accessKey;

    /**
     * minio密码
     */
    private String secretKey;

    /**
     * 文件桶的名称
     */
    private String bucketName;

}

4、minio工具类 (根据2021.11 官方最新api的语法)

``

import com.smart.model.MinioProperties;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * @author peiyuxiang
 * @date 2021/11/10
 */
@Slf4j
@Component
public class MinioUtil {
    @Autowired
    MinioProperties minIoProperties;

    private static MinioClient minioClient;

    /**
     * 初始化minio配置
     *
     * @param :
     * @return: void
     */
    @PostConstruct
    public void init() {
        try {
            minioClient =
                    MinioClient.builder()
                            .endpoint(minIoProperties.getUrl())
                            .credentials(minIoProperties.getAccessKey(), minIoProperties.getSecretKey())
                            .build();
            createBucket(minIoProperties.getBucketName());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("初始化minio配置异常: 【{}】", e.fillInStackTrace());
        }
    }


    /**
     * 判断 bucket是否存在
     *
     * @param bucketName:桶名
     * @return: boolean
     */
    @SneakyThrows(Exception.class)
    public boolean bucketExists(String bucketName) {
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }

    /**
     * 创建 bucket
     *
     * @param bucketName:桶名
     * @return: void
     */
    @SneakyThrows(Exception.class)
    public void createBucket(String bucketName) {
        boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        if (!isExist) {
            minioClient.makeBucket(
                    MakeBucketArgs.builder()
                            .bucket(bucketName)
                            .build());
        }

    }

    /**
     * 获取全部bucket
     *
     * @param :
     * @return: java.util.List<io.minio.messages.Bucket>
     */
    @SneakyThrows(Exception.class)
    public List<Bucket> getAllBuckets() {
        return minioClient.listBuckets();
    }


    /**
     * 文件上传
     *
     * @param bucketName:桶名
     * @param fileName:文件名
     * @param stream:       文件流
     * @return: java.lang.String : 文件url地址
     */
    @SneakyThrows(Exception.class)
    public String upload(String bucketName, String fileName, InputStream stream) {
        minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(
                stream, -1, 10485760)
                .build());
        return getFileUrl(bucketName, fileName);
        
    }

    /**
     * 文件上传
     *
     * @param bucketName:桶名
     * @param file:文件
     * @return: java.lang.String : 上传文件名
     */
    @SneakyThrows(Exception.class)
    public String upload(String bucketName, MultipartFile file) {
        final InputStream is = file.getInputStream();
        String originalFilename = file.getOriginalFilename();
        String fileName = bucketName + "_" + DateUtil.formatDateTime(new Date(), "yyyyMMddHHmmssSSS") + originalFilename.substring(originalFilename.lastIndexOf("."));
        minioClient.putObject(
                PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(
                        is, file.getSize(), -1)
                        .contentType(file.getContentType())
                        .build());
        is.close();
        return fileName;
    }

    /**
     * 删除文件
     *
     * @param bucketName:桶名
     * @param fileName:文件名
     * @return: void
     */
    @SneakyThrows(Exception.class)
    public void deleteFile(String bucketName, String fileName) {
        minioClient.removeObject(
                RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());

    }

    /**
     * 下载文件
     *
     * @param bucketName:桶名
     * @param fileName:文件名
     * @param response:
     * @return: void
     */
    @SneakyThrows(Exception.class)
    public void download(String bucketName, String fileName, HttpServletResponse response) {
        // 获取对象的元数据
        ObjectStat stat = minioClient.statObject(
                StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
        response.setContentType(stat.contentType());
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        InputStream stream = null;
        try {
            stream = minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .build());
            IOUtils.copy(stream, response.getOutputStream());
            stream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获得文件流
     * @param bucketName
     * @param fileName
     * @return
     */
    @SneakyThrows(Exception.class)
    public InputStream getFile(String bucketName, String fileName) {
        InputStream stream = null;
        try {
            stream = minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stream;
    }


    /**
     * 获取minio文件的下载地址
     *
     * @param bucketName:桶名
     * @param fileName:文件名
     * @return: java.lang.String
     */
    @SneakyThrows(Exception.class)
    public String getFileUrl(String bucketName, String fileName) {
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.DELETE)
                        .bucket(bucketName)
                        .object(fileName)
                        .expiry(24 * 60 * 60)
                        .build());
    }

}

5、controller

``

import com.smart.model.MinioProperties;
import com.smart.util.MinioUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

/**
 * @author peiyuxiang
 * @date 2021/11/10
 */
@RestController
@RequestMapping("/api/minio")

public class MinIoController {
    @Resource
    MinioProperties minIoProperties;
    @Resource
    MinioUtil minioUtil;

    @PostMapping(value = "/upload")
    public String upload(@RequestParam("file") MultipartFile file) throws Exception {
        String fileUrl = minioUtil.upload(minIoProperties.getBucketName(), file);
        return "上传文件名:" + fileUrl;
    }


    @GetMapping(value = "/download")
    public void download(@RequestParam("fileName") String fileName, HttpServletResponse response) {
        minioUtil.download(minIoProperties.getBucketName(), fileName, response);
    }


    @GetMapping(value = "/delete")
    public String delete(@RequestParam("fileName") String fileName) {
        minioUtil.deleteFile(minIoProperties.getBucketName(), fileName);
        return "删除成功";
    }

}

注意事项:首先端口号一定要注意,初始化出问题的时候可以debug排查,然后尽量根据官方文档最新的api来写方法(不要看国内中文版,太旧了),因为api更新速度非常快!!最后大家一定要注意pom依赖的不同版本的问题,这一版写法目前只支持7.1.0版本。