Spring Boot configures MinIO (realize file upload, read, download, delete)

1. MinIO


        MinIO is an object storage service based on the Apache License v2.0 open source protocol. It is compatible with the Amazon S3 cloud storage service interface, and is very suitable for storing large-capacity unstructured data, such as pictures, videos, log files, backup data, and container/virtual machine images, etc., and an object file can be of any size, from several kb to a maximum of 5T.

        MinIO is a very lightweight service that can be easily integrated with other applications, like NodeJS, Redis or MySQL.

2. MinIO installation and startup


       Since MinIO is a separate server and needs to be deployed separately, please refer to the following blog for the use of MinIO on Windows systems.

Windows MinIO usage tutorial (start, login, change password)

3. pom.xml (maven dependency file)


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


 Four, applicatin.properties (configuration file)


 

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


5. Write Java business classes


        The methods involved in minio are: judging whether the bucket exists, creating a bucket, uploading files, reading files, downloading files, deleting files, etc.

1. StorageProperty storage attribute class:

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 configuration class:

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
@Configuration
public 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 tools

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
@Component
public 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


      File upload, file read, file download, file delete interfaces are as follows:

/**
 * @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 ? "删除成功" : "删除失败";
    }


}


7. Debugging results


 1. File upload

 files on minio 


2. File download 


3. File deletion 

 Let's see if the file has been deleted on minio

Guess you like

Origin blog.csdn.net/Angel_asp/article/details/128535684