SpringBoot整合Minio,一篇带你入门使用Minio

本文介绍SpringBoot如何整合Minio,解决文件存储问题

前言

参考链接:

环境搭建

项目环境搭建

将minio单独封装成一个module,上层导入依赖,比如api module
在这里插入图片描述
在api 模块,测试接口
在这里插入图片描述

添加依赖库

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-learn</artifactId>
        <groupId>org.ym</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>learn-common-minio</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.4.5</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
    </dependencies>

</project>

yml配置

application.yml配置,配置minio基本信息

server:
  port: 9203

minio:
  endpoint: http://127.0.0.1:9000
  bucketName: learn-minio
  accessKey: minioadmin
  secretKey: minioadmin

spring:
  application:
    name: learn-api
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

Docker安装minio

首先要创建本机data目录/Users/yangmiao/config/docker/data/minio,至于Docker常见命令的使用,参考我的另一篇文章Docker常见命令使用

sudo docker run -p 9000:9000 -p 9090:9090 \
--name minio \
-d --restart=always \
-e "MINIO_ACCESS_KEY=minioadmin" \
-e "MINIO_SECRET_KEY=minioadmin" \
-v /Users/yangmiao/config/docker/data/minio:/data \
minio/minio server \
/data --console-address ":9090" -address ":9000"

镜像启动成功后,浏览器访问:http://localhost:9090/,输入用户名和密码minioadmin。
在这里插入图片描述

代码实现

MiniConfig

package com.ym.learn.minio.config;

import com.ym.learn.minio.service.MinioService;
import com.ym.learn.minio.service.impl.MinioServiceImpl;
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author: Yangmiao
 * @Date: 2023/4/21 23:04
 * @Desc: minio基础配置
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    
    
    /**
     * 服务地址
     */
    private String endpoint;
    /**
     * 访问key
     */
    private String accessKey;
    /**
     * 密钥
     */
    private String secretKey;
    /**
     * 桶名称
     */
    private String bucketName;

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

    @Bean
    public MinioService minioService(){
    
    
        return new MinioServiceImpl();
    }
}

在这里插入图片描述

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.ym.learn.minio.config.MinioConfig

service

package com.ym.learn.minio.service;

import com.ym.learn.minio.config.MinioConfig;
import io.minio.MinioClient;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @Author: Yangmiao
 * @Date: 2023/4/21 23:09
 * @Desc: minio服务
 */
public interface MinioService {
    
    
    /**
     * 判断bucket是否存在
     * @param bucketName
     * @return
     */
    boolean bucketExists(String bucketName);

    /**
     * 创建bucket
     * @param bucketName
     * @return
     */
    boolean createBucket(String bucketName);

    /**
     * 删除bucket
     * @param bucketName
     * @return
     */
    boolean removeBucket(String bucketName);

    /**
     * 获取所有的bucket
     * @return
     */
    List<Bucket> getAllBuckets();

    /**
     * 上传文件
     * @param multipartFile
     * @return
     */
    String upload(MultipartFile multipartFile);

    /**
     * 下载文件
     * @param fileName
     * @param res
     */
    void download(String fileName, HttpServletResponse res);

    /**
     * 删除文件
     * @param fileName
     * @return
     */
    boolean remove(String fileName);

    /**
     * 预览文件
     * @param fileName
     * @return
     */
    String preview(String fileName);

    /**
     * 查看所有的文件对象
     * @return
     */
    List<Item> getAllFiles();

}

package com.ym.learn.minio.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.ym.learn.minio.config.MinioConfig;
import com.ym.learn.minio.service.MinioService;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Yangmiao
 * @Date: 2023/4/21 23:12
 * @Desc:
 */
@Service
@Slf4j
public class MinioServiceImpl implements MinioService {
    
    
    @Autowired
    private MinioConfig minioConfig;
    @Autowired
    private MinioClient minioClient;

    @Override
    public boolean bucketExists(String bucketName) {
    
    
        if (StrUtil.isEmpty(bucketName)){
    
    
            return false;
        }
        boolean res = false;
        try {
    
    
            res = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
    
    
            log.error("bucketExists error: {}",e.getMessage());
            e.printStackTrace();
            return false;
        }
        return res;
    }

    @Override
    public boolean createBucket(String bucketName) {
    
    
        if (StrUtil.isEmpty(bucketName)){
    
    
            return false;
        }
        try {
    
    
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }catch (Exception e){
    
    
            log.error("createBucket error: {}",e.getMessage());
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public boolean removeBucket(String bucketName) {
    
    
        if (StrUtil.isEmpty(bucketName)){
    
    
            return false;
        }
        try {
    
    
            minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
        }catch (Exception e){
    
    
            log.error("removeBucket error: {}",e.getMessage());
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public List<Bucket> getAllBuckets() {
    
    
        try {
    
    
            return minioClient.listBuckets();
        }catch (Exception e){
    
    
            log.error("getAllBuckets error: {}",e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String upload(MultipartFile multipartFile) {
    
    
        if (multipartFile == null){
    
    
            return null;
        }
        String fileName = multipartFile.getOriginalFilename();
        if (StrUtil.isBlank(fileName)){
    
    
            throw new RuntimeException("upload fail!");
        }
        fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+"_"+UUID.randomUUID().toString().replaceAll("-","")+
                fileName.substring(fileName.lastIndexOf("."));
        log.debug("upload: fileName {}",fileName);
        try {
    
    
            minioClient.putObject(PutObjectArgs.builder()
                            .bucket(minioConfig.getBucketName())
                            .object(fileName)
                            .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
                            .contentType(multipartFile.getContentType())
                            .build());
        } catch (Exception e) {
    
    
            log.error("upload error: {}",e.getMessage());
            e.printStackTrace();
            return null;
        }
        String url = minioConfig.getEndpoint()+"/"+minioConfig.getBucketName()+"/"+fileName;
        return url;
    }

    @Override
    public void download(String fileName, HttpServletResponse res) {
    
    
        if (StrUtil.isEmpty(fileName)){
    
    
            return;
        }
        ByteArrayOutputStream out = null;
        try {
    
    
            GetObjectResponse objectResponse = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .build());

            out = new ByteArrayOutputStream();
            IoUtil.copy(objectResponse,out);
            res.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            res.setContentLength(out.toByteArray().length);
            res.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            try(ServletOutputStream stream = res.getOutputStream()){
    
    
                stream.write(out.toByteArray());
                stream.flush();
            }
        }catch (Exception e){
    
    
            log.error("download error: {}",e.getMessage());
            e.printStackTrace();
        }finally {
    
    
            if (out != null){
    
    
                try {
    
    
                    out.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public boolean remove(String fileName) {
    
    
        if (StrUtil.isEmpty(fileName)){
    
    
            return false;
        }
        try {
    
    
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileName).build());
        }catch (Exception e){
    
    
            log.error("remove error: {}",e.getMessage());
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public String preview(String fileName) {
    
    
        if (StrUtil.isEmpty(fileName)){
    
    
            return null;
        }
        try {
    
    
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .method(Method.GET)
                    .build());
        }catch (Exception e){
    
    
            log.error("preview error: {}",e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public List<Item> getAllFiles() {
    
    
        List<Item> itemList = new ArrayList<>();
        try {
    
    
            Iterable<Result<Item>> listObjects = minioClient.listObjects(
                    ListObjectsArgs.builder()
                            .bucket(minioConfig.getBucketName())
                            .build());
            try {
    
    
                for (Result<Item> item:listObjects){
    
    
                    itemList.add(item.get());
                }
            }catch (Exception e){
    
    
                log.error("getAllFiles error, get item fail! {}",e.getMessage());
                e.printStackTrace();
                return null;
            }
        }catch (Exception e){
    
    
            log.error("getAllFiles error {}",e.getMessage());
            e.printStackTrace();
            return null;
        }
        return itemList;
    }
}

controller

package com.ym.learn.api.controller;

import com.ym.learn.core.api.R;
import com.ym.learn.minio.config.MinioConfig;
import com.ym.learn.minio.service.MinioService;
import io.minio.messages.Bucket;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @Author: Yangmiao
 * @Date: 2023/4/22 23:00
 * @Desc:
 */
@Api(tags = "minio接口")
@RestController
@RequestMapping("/file")
@Slf4j
public class MinioController {
    
    
    @Autowired
    private MinioService minioService;
    @Autowired
    private MinioConfig minioConfig;

    @ApiOperation(value = "判断bucket是否存在")
    @GetMapping("/bucketExist")
    public R bucketExist(@RequestParam("bucketName")String bucketName){
    
    
        boolean exists = minioService.bucketExists(bucketName);
        return R.ok(exists);
    }

    @ApiOperation(value = "创建bucket")
    @GetMapping("/createBucket")
    public R createBucket(String bucketName){
    
    
        boolean ret = minioService.createBucket(bucketName);
        return R.ok(ret);
    }

    @ApiOperation(value = "删除bucket")
    @GetMapping("/removeBucket")
    public R removeBucket(String bucketName){
    
    
        boolean removeBucket = minioService.removeBucket(bucketName);
        return R.ok(removeBucket);
    }

    @ApiOperation(value = "获取所有的bucket")
    @GetMapping("/getAllBucket")
    public R getAllBucket(){
    
    
        List<Bucket> allBuckets = minioService.getAllBuckets();
        return R.ok(allBuckets);
    }

    @ApiOperation(value = "上传文件")
    @PostMapping("/uploadFile")
    public R uploadFile(@RequestParam("file") MultipartFile file){
    
    
        String upload = minioService.upload(file);
        return R.ok(upload);
    }

    @ApiOperation(value = "查看Image")
    @GetMapping("/preview")
    public R preview(String fileName){
    
    
        String preview = minioService.preview(fileName);
        return R.ok(preview);
    }

    @ApiOperation(value = "下载文件")
    @GetMapping("/downloadFile")
    public R downloadFile(String fileName, HttpServletResponse response){
    
    
        minioService.download(fileName,response);
        return R.ok();
    }

    @ApiOperation(value = "删除文件")
    @PostMapping("/removeFile")
    public R removeFile(String url){
    
    
        String objName = url.substring(url.lastIndexOf(minioConfig.getBucketName()+"/") + minioConfig.getBucketName().length()+1);
        boolean remove = minioService.remove(objName);
        return R.ok(remove);
    }![在这里插入图片描述](https://img-blog.csdnimg.cn/f9965e88a5b84d62ba029ffc86e065f3.jpeg#pic_center)


}

测试

由于项目已引入了Knife4j,本文采用了Knife4j和ApiPost测试
在这里插入图片描述
在这里插入图片描述
查看minio是否上传成功图片,以及bucket是否成功创建。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/baidu_33256174/article/details/130333217
今日推荐