SpringBoot 集成Minio实现上传和图片访问

业务背景

正常情况一般我们对文件的上传会优先考虑OSS,可是有些情况特殊的甲方有自己的机房;也不会去考虑OSS,但是要又考虑的文件上传压缩安全的问题;我这里使用的就是OSS来保证数据安全以及压缩(我这边是单体服务)。

什么是Minio

我也不太清楚感兴趣的可以看看官网也提供了demo代码

这是Java的demo里面的方法很全自己看一下啦

SpringBoot 集成Minio实现上传和图片访问_第1张图片

引入pom

		
        
            io.minio
            minio
            8.3.4
        
        
            me.tongfei
            progressbar
            0.5.3
        
        
            com.squareup.okhttp3
            okhttp
            4.8.1
        

配置文件

minio:
  endpoint: http://127.0.0.1:9000
  accessKey: myname
  secretKey: mypassword

引入配置

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * minio 属性值
 */
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProp {
    /**
     * 连接url
     */
    private String endpoint;
    /**
     * 用户名
     */
    private String accessKey;
    /**
     * 密码
     */
    private String secretKey;
}

config配置

import com.ruoyi.web.art.dto.MinioProp;
import io.minio.BucketExistsArgs;
import io.minio.MinioClient;
import io.minio.messages.Bucket;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;


@Slf4j
@Component
@Configuration
public class MinioClientConfig {

    @Resource
    private MinioProp minioProp;

    @Getter
    private static MinioClient minioClient;


    @SneakyThrows(Exception.class)
    public static boolean bucketExists(String bucketName) {
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }


    @SneakyThrows(Exception.class)
    public static List getAllBuckets() {
        return minioClient.listBuckets();
    }


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

}

工具类

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.web.art.conf.MinioClientConfig;
import com.ruoyi.web.art.dto.MinioProp;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

@Slf4j
@Component
public class MinioUtils {
    @Resource
    private MinioProp minioProp;

    /**
     * Minio文件上传
     *
     * @param file       文件实体
     * @param bucketName 所存文件夹(桶名)
     */
    public AjaxResult minioUpload(MultipartFile file, String bucketName) {
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("code", 500);
        try {
            MinioClient minioClient = MinioClientConfig.getMinioClient();
            // 判断上传文件是否为空
            if (null == file || 0 == file.getSize()) {
                ajaxResult.put("msg", "上传文件不能为空");
                return ajaxResult;
            }
            // 文件名
            String fileName = file.getOriginalFilename();
            // 文件名
            // 新的文件名 = 存储桶名称_时间戳.后缀名
            String fileNameNew = bucketName + "_" + System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf("."));
            InputStream inputStream = file.getInputStream();
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileNameNew)
                    .stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build();
            //文件名称相同会覆盖
            minioClient.putObject(objectArgs);
            String fileUrl = minioProp.getEndpoint() + "/" + bucketName + "/" + fileNameNew;
            ajaxResult.put("code", 200);
            ajaxResult.put("msg", fileUrl);
            return ajaxResult;
        } catch (Exception e) {
            e.printStackTrace();
            return ajaxResult;
        }
    }


    /**
     * 下载文件
     *
     * @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(StandardCharsets.ISO_8859_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;
        }
    }
}
 
 

MinioController

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.art.utils.MinioUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

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

@Controller
@RequestMapping("/minio")
public class MinioController {

    @Resource
    private MinioUtils minioUtils;


    /**
     * 上传
     */
    @PreAuthorize("@ss.hasPermi('minio:insert')")
    @Log(title = "Minio", businessType = BusinessType.INSERT)
    @PostMapping("/upload")
    @ResponseBody
    public AjaxResult upload(@RequestParam(name = "file", required = false) MultipartFile file) {
        minioUtils.minioUpload(file, "test");
        return AjaxResult.success();
    }

    @PreAuthorize("@ss.hasPermi('minio:query')")
    @PostMapping("/getFileInputStream")
    @ResponseBody
    public AjaxResult getFileInputStream(HttpServletResponse response) {
        minioUtils.downloadFile("test", "test_1690439416626.jpg", response);
        return AjaxResult.success();
    }

}

controller

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.art.utils.MinioUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

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

@Controller
@RequestMapping("/minio")
public class MinioController {

    @Resource
    private MinioUtils minioUtils;


    /**
     * 上传
     */
    @PreAuthorize("@ss.hasPermi('minio:insert')")
    @Log(title = "Minio", businessType = BusinessType.INSERT)
    @PostMapping("/upload")
    @ResponseBody
    public AjaxResult upload(@RequestParam(name = "file", required = false) MultipartFile file) {
        return  minioUtils.minioUpload(file, "test");
    }

    @PreAuthorize("@ss.hasPermi('minio:query')")
    @PostMapping("/getFileInputStream")
    @ResponseBody
    public AjaxResult getFileInputStream(HttpServletResponse response) {
        minioUtils.downloadFile("test", "test_1690439416626.jpg", response);
        return AjaxResult.success();
    }

}

总结

Minio中Buckets有三种访问策略为:Private、Public、Custom
Private是私有访问我的理解是只有当前用户可以访问或者是只有该用户配置了这个bukets才能进行操作(生产上的一般为该访问模式仅限个人理解我也第一次接错Minio)
Public是指公共访问任何人都可以进行读写(你刚上传的时候可以打开看一下确定你的功能可以实现并且是你想要的)
Custom按照规则进行访问和读写(没研究明白,谁懂可以评论区留言一下我去了解一下)

你可能感兴趣的:(spring,boot,后端,java)