SpringBoot引入MinIO实现图片文件上传,下载(三)

本章内容:Springboot2.0引入MinIO实现文件的上传和下载功能,以及引入过程中遇到的Bug;

Docker 快速部署 MinIo

引入依赖配置

pom.xml中引入MinIO依赖



	io.minio
	minio
	8.3.1
	
    
		
			com.squareup.okhttp3
			okhttp
		
	




	com.squareup.okhttp3
	okhttp
	4.8.1

application.yml中配置MinIO

server:
  port: 6001
min:
  io:
    secure: false
    endpoint: http://127.0.0.1:9000
    point: 80
    accessKey: FASDFFSFDG7EXASDFAD
    secretKey: eJalrSDtnFEMI/ASDF3GSD/bPxRfiCYEXASDFADEY

核心编码

MinIO 属性配置文件以及将MinIO注入到spring管理

package net.sm.util.minio;

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author GGYYJJ
 * @Date 2021/10/13 10:45
 * @Version 1.0
 * @Title
 * @Desc
 */
@Configuration
@Data
public class MinIoConfig {
    /**
     * Minio 服务地址
     */
    @Value("${min.io.endpoint}")
    private String endpoint;

    /**
     * Minio 服务端口号
     */
    @Value("${min.io.point}")
    private Integer point;

    /**
     * Minio ACCESS_KEY
     */
    @Value("${min.io.accessKey}")
    private String accessKey;

    /**
     * Minio SECRET_KEY
     */
    @Value("${min.io.secretKey}")
    private String secretKey;

    /**
     * Minio 是否为https 请求,true 地址为http,false地址为http
     */
    @Value("${min.io.secure}")
    private boolean secure;

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

}

minio工具类,列出了常用文件操作,详细API需求请参考官方文档:

官网以及API  |  中文API

package net.sm.util.minio;

import com.alibaba.fastjson.JSONObject;
import io.minio.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import jodd.io.FastByteArrayOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author GGYYJJ
 * @Date 2021/10/12 13:28
 * @Version 1.0
 * @Title
 * @Desc
 */
@Component
public class MinIoUtil {
    @Autowired
    private MinioClient minioClient;

    /**
     * 查看存储bucket是否存在
     * @param bucketName 存储bucket
     * @return boolean
     */
    public Boolean bucketExists(String bucketName) {
        Boolean found;
        try {
            found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return found;
    }

    /**
     * 创建存储bucket
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 删除存储bucket
     * @param bucketName 存储bucket名称
     * @return Boolean
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 文件上传
     * @param file 文件
     * @param bucketName 存储bucket
     * @return Boolean
     */
    public Boolean upload(MultipartFile file, String bucketName) {
        try {
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(file.getOriginalFilename())
                    .stream(file.getInputStream(),file.getSize(),-1).contentType(file.getContentType()).build();
            //文件名称相同会覆盖
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 文件下载
     * @param bucketName 存储bucket名称
     * @param fileName 文件名称
     * @param res response
     * @return Boolean
     */
    public void download(String bucketName, String fileName, HttpServletResponse res) {
        GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName)
                .object(fileName).build();
        try (GetObjectResponse response = minioClient.getObject(objectArgs)){
            byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){
                while ((len=response.read(buf))!=-1){
                    os.write(buf,0,len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                //设置强制下载不打开
                res.setContentType("application/force-download");
                res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                try (ServletOutputStream stream = res.getOutputStream()){
                    stream.write(bytes);
                    stream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 查看文件对象
     * @param bucketName 存储bucket名称
     * @return 存储bucket内文件对象信息
     */
    public List listObjects(String bucketName) {
        Iterable> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        List objectItems = new ArrayList<>();
        try {
            for (Result result : results) {
                Item item = result.get();
                JSONObject objectItem = new JSONObject();
                objectItem.put("object_name",item.objectName());
                objectItem.put("size",item.size());
                objectItems.add(objectItem);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return objectItems;
    }

    /**
     * 批量删除文件对象
     * @param bucketName 存储bucket名称
     * @param objects 对象名称集合
     */
    public Iterable> removeObjects(String bucketName, List objects) {
        List dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
        Iterable> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
        return results;
    }
}

测试

controller控制器入口方法,上传完之后可以在管理后台查看到。

package net.sm.controller;

import com.alibaba.fastjson.JSONObject;
import net.sm.util.minio.MinIoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author GGYYJJ
 * @Date 2021/9/29 17:48
 * @Version 1.0
 * @Title
 * @Desc
 */
@RestController
@RequestMapping("/api/commodity/v1/")
public class CommodityController extends BaseController{

    @Autowired
    private MinIoUtil minIoUtil;

    @RequestMapping("/uploadFile")
    public void upload(@RequestParam("file") MultipartFile file) throws Exception {
        System.out.println(minIoUtil.upload(file, "my-bucketname"));

    }

    /**
     * minio下载文件
     */
    @GetMapping("/download")
    public void download(HttpServletResponse res){
        minIoUtil.download("my-bucketname","logo.png", res);
    }

}

PostMan测试图片上传

SpringBoot引入MinIO实现图片文件上传,下载(三)_第1张图片

 登录MinIO管理后台,找到对应的bucket下就可以看到上传成功的图片;

SpringBoot引入MinIO实现图片文件上传,下载(三)_第2张图片

文件下载,打开浏览访问地址,http://127.0.0.1:6001/api/commodity/v1/download ,后台返回的文件流在浏览器进行下载;

 过程中遇到的问题:

1、在引入MinIo的时候,MinIO里面依赖的okhttp去除掉,并重新引入高版本的okhttp包。否则会报错;

okhttp3.RequestBody: file:/D:/Work20170505/mavn-repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar

Correct the classpath of your application so that it contains a single, compatible version of okhttp3.RequestBody
2、在Maven项目编译过程中,如果遇上缺少依赖,或是已引入依赖还报错的,在项目根目录执行mvn clean install;idea 要开启pom自动导入更新jar功能;

你可能感兴趣的:(MinIO文件存储系统,java,spring,boot,spring,ide,分布式)