前面说了下minio的安装和配置,这次,我们来看看怎么和springboot进行集成使用。
首先说一下版本:
Springboot版本:2.2.5.RELEASE
minio版本:8.x
官方文档:https://docs.min.io/docs/java-client-quickstart-guide.html
依赖
添加依赖,官方给出的版本是8.3.0,但是用这个版本后会报错:

然后我们将版本稍微降低下:
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.2.1</version>
</dependency>
创建minioClient对象

由官方的文档可以看出,创建minioClient的方式有很多种。
要的参数无非就是:
- url ip地址
- port 端口号
- access key 用户名
- secret key 密码
- bucketName 桶名称
- userSSL 是否使用ssl
那我们首先就创建一个MinioClientProp文件,把这些参数写在配置文件中,然后通过参数注入的方式来加载参数:
@Configuration
@ConfigurationProperties("bearweb.minio")
@Slf4j
@Data
public class MinioClientProp implements InitializingBean {
    private String url;
    private Integer port;
    private String accessKey;
    private String secretKey;
    private Boolean userSSL;
    private String bucketName;
    @Bean
    public MinioClient minioClient() {
        MinioClient minioClient;
        try {
            // 创建minioClient 
            minioClient = MinioClient.builder().endpoint(url, port, userSSL).credentials(accessKey, secretKey).build();
            // 判断是否存在桶,不存在则创建桶
            boolean hasBucket = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!hasBucket) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RuntimeException("minioClient初始化失败");
        }
        return minioClient;
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("-------minio初始化完成---------");
    }
}
yaml中的配置文件如下:
spring:
  minio:
    url: 192.168.0.3
    port: 9002
    accessKey: 用户名
    secretKey: 密码
    userSSL: false
    bucketName: bearweb
当项目启动没有问题,就说明配置没有问题,如果启动报错,ip或者端口或者用户名密码错误,需要按照按照启动的配置填写正确后可启动正常。
封装自己常用的工具类
官方地址:https://docs.min.io/docs/java-client-api-reference.html

其实官方地址已经给出了操作文档和demo,我们只需要按照自己的需要封装即可:
@Component
@Slf4j
public class MinioOpsUtil {
    @Autowired
    private MinioClientProp minioClientConfig;
    @Autowired
    private MinioClient minioClient;
    public StatObjectResponse getFileInfo(String objectName, String bucketName){
        try {
            if (StringUtils.isBlank(bucketName)){
                bucketName = minioClientConfig.getBucketName();
            } else {
                throw new Exception("操作失败!桶不存在!");
            }
            return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            return null;
        }
    }
    public void download(String objectName, String bucketName, String fileName,  HttpServletResponse  response) throws Exception{
        if (StringUtils.isNotBlank(bucketName)){
            if (!this.bucketExists(bucketName)){
                throw new Exception("操作失败!桶不存在!");
            }
        } else {
            bucketName = minioClientConfig.getBucketName();
        }
        InputStream stream = minioClient.getObject(GetObjectArgs.builder()
                                        .bucket(bucketName)
                                        .object(objectName)
                                        .build());
        response.setContentType("application/force-download");
        response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
        response.setCharacterEncoding("UTF-8");
        IOUtils.copy(stream, response.getOutputStream());
    }
    /**
     * 上传单个文件到指定的桶
     * @param file MultipartFile
     * @param bucketName 桶名称,如果不存在,则系统配置的桶
     * @throws Exception
     */
    public String upload(MultipartFile file, String bucketName) throws Exception{
        // 判断是否传入桶名称
        if (StringUtils.isNotBlank(bucketName)){
            if (!this.bucketExists(bucketName)){
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } else {
            bucketName = minioClientConfig.getBucketName();
        }
        // 获取原始,名称
        String fileName = file.getOriginalFilename();
        // 截取新的名称
        String objectName = UUID.randomUUID().toString().replaceAll("-", "") +
                                        fileName.substring(fileName.lastIndexOf("."), fileName.length());
        // 日期前缀
        String folderPrefix = this.timeFolder();
        objectName = folderPrefix + "/" +objectName;
        // 上传
        minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs
                .builder().method(Method.GET).bucket(bucketName).object(objectName).build());
        // 原始路径为 ip:port/bucketName/objectName?minio自带参数
        // 截取后只保留 ip:port/bucketName/objectName
        url = url.split("\\?")[0];
        return url;
    }
    /**
     * 上传多个文件到系统配置的桶
     * @param files MultipartFile
     * @param bucketName 桶名称,如果不存在,则系统配置的桶
     * @throws Exception
     */
    public List<String> uploadBatch(MultipartFile[] files, String bucketName) throws Exception{
        // 判断是否传入桶名称
        if (StringUtils.isNotBlank(bucketName)){
            if (!this.bucketExists(bucketName)){
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } else {
            bucketName = minioClientConfig.getBucketName();
        }
        String finalBucketName = bucketName;
        List<String> urlList = Collections.synchronizedList(new ArrayList<>());
        Arrays.asList(files).parallelStream().forEach(file -> {
            try {
                String filePath = this.upload(file, finalBucketName);
                urlList.add(filePath);
            } catch (Exception e) {
                log.info("文件上传失败,文件名:{}",file.getOriginalFilename());
                throw new RuntimeException("文件上传失败", e);
            }
        });
        return urlList;
    }
    /**
     * 从指定的桶删除文件
     * @param objectName 文件名称
     * @param bucketName 桶名称,如果不存在,则系统配置的桶
     * @throws Exception
     */
    public void delete(String objectName, String bucketName) throws Exception{
        // 判断是否传入桶名称
        if (StringUtils.isBlank(bucketName)){
            bucketName = minioClientConfig.getBucketName();
        } else {
            if (!this.bucketExists(bucketName)){
                throw new Exception("操作失败!桶不存在!");
            }
        }
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }
    /**
     * 批量从指定的桶删除文件
     * @param objectNames 文件名称
     * @param bucketName 桶名称,如果不存在,则系统配置的桶
     * @throws Exception
     */
    public void deleteBatch(String[] objectNames, String bucketName) throws Exception{
        // 判断是否传入桶名称
        if (StringUtils.isBlank(bucketName)){
            bucketName = minioClientConfig.getBucketName();
        } else {
            if (!this.bucketExists(bucketName)){
                throw new Exception("操作失败!桶不存在!");
            }
        }
        String finalBucketName = bucketName;
        Arrays.stream(objectNames).parallel().forEach(objectName ->{
            try {
                minioClient.removeObject(RemoveObjectArgs.builder().bucket(finalBucketName).object(objectName).build());
            } catch (Exception e) {
                log.info("文件删除失败,文件名:{}", objectName);
                throw new RuntimeException("文件上传失败", e);
            }
        });
    }
    /**
     * 获取当前时间转换成字符串
     * @return
     */
    private String timeFolder(){
        LocalDate time = LocalDate.now();
        String format = time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return format;
    }
    /**
     * 判断是否存在传入的桶,不存在创建
     * @param bucketName
     * @throws IOException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws InsufficientDataException
     * @throws NoSuchAlgorithmException
     * @throws ServerException
     * @throws InternalException
     * @throws XmlParserException
     * @throws ErrorResponseException
     */
    private Boolean bucketExists(String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException,
                                        NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        return found;
    }
}
测试
首先控制台是没有今天的数据的:

首先是文件的上传,由于我们没有指定桶,默认上传到系统配置文件配置的桶里面:
@Autowired
    private MinioOpsUtil minioOpsUtil;
@PostMapping("/uploadUserPicture")
    public CommonResult uploadUserPicture(@RequestParam("file") MultipartFile file) throws Exception {
        String filePath = minioOpsUtil.upload(file, null);
        return CommonResult.success(filePath);
    }

这个就是刚才上传的文件:

其他我也不演示了,应该没啥问题。
小弟我也是第一次接触minio,如有纰漏,欢迎各位大佬指出。
 
             
           
             
          
评论区