SpringBoot integrates Minio, an article to get you started using Minio

This article introduces how SpringBoot integrates Minio to solve file storage problems

foreword

Reference link:

Environment build

Project environment construction

Encapsulate minio separately into a module, and the upper layer imports dependencies, such as the api module
insert image description here
in the api module, and the test interface
insert image description here

Add dependent library

<?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 configuration

application.yml配置, configure minio basic information

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 install minio

First of all, you need to create the local data directory . As for the use of common Docker commands/Users/yangmiao/config/docker/data/minio , please refer to my other article.

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"

After the mirror image starts successfully, visit: in the browser http://localhost:9090/, and enter the user name and password minioadmin.
insert image description here

Code

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();
    }
}

insert image description here

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)


}

test

Since the project has introduced Knife4j, this article uses Knife4j and ApiPost to test
insert image description here
insert image description here
whether minio uploads the image successfully and whether the bucket is successfully created.
insert image description here

Guess you like

Origin blog.csdn.net/baidu_33256174/article/details/130333217