Springboot集成minio上传文件

文章目录

  • 1. minio的安装配置
  • 2. springboot配置pom.xml
    • 请注意版本号:8.2.1
    • 版本过高或者过低都可能会报错
  • 3. yml 配置文件
  • 4. MinioConfig 配置类
  • 5. MinioUtils 工具类
  • 6. ObjectWriteResponse 上传后返回的对象
    • region() 方法可以获取上传后的服务端图片对应的完整访问路径

1. minio的安装配置

  • 官方网址:https://docs.min.io/docs/minio-quickstart-guide.html
    Springboot集成minio上传文件_第1张图片

  • 本人使用的是docker安装到centos7
    使用的是管理员用户

mkdir -p ~/minio/data

作用:在当前用户目录下创建 data文件夹

  • 也可以直接创建绝对路径的文件夹
mkdir -p /minio/data

这是在根目录创建 /minio/data
Springboot集成minio上传文件_第2张图片

  • docker search xxx 搜索镜像文件
docker search minio

Springboot集成minio上传文件_第3张图片

  • docker 启动容器
docker run \
  -p 9000:9000 \
  -p 9001:9001 \
  --name minio1 \
  -v /minio/data:/data \
  -e "MINIO_ROOT_USER=username" \
  -e "MINIO_ROOT_PASSWORD=password" \
  quay.io/minio/minio server /data --console-address ":9001"

-v /minio/data:/data 刚才创建的路径映射minio服务器对应的data保存路径
MINIO_ROOT_USER=xxxx 理解为 用户名
MINIO_ROOT_PASSWORD 理解为密码 最少8位

Springboot集成minio上传文件_第4张图片

  • 访问 http://127.0.0.1:9000
    如果是本机用上面的地址,如果不是就换做服务器的地址
    Springboot集成minio上传文件_第5张图片
    我这里是已经上传了文件 所以有文件在里面

2. springboot配置pom.xml

请注意版本号:8.2.1


		<dependency>
		    <groupId>io.miniogroupId>
		    <artifactId>minioartifactId>
		    <version>8.2.1version>
		dependency>

版本过高或者过低都可能会报错

  • 我用 8.3.3版本,系统报错提示
Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    io.minio.S3Base.(S3Base.java:98)

The following method did not exist:

    okhttp3.RequestBody.create([BLokhttp3/MediaType;)Lokhttp3/RequestBody;

The method's class, okhttp3.RequestBody, is available from the following locations:

    jar:file:/D:/Program/Maven/apache-maven-3.8.4-repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar!/okhttp3/RequestBody.class

The class hierarchy was loaded from the following locations:

    okhttp3.RequestBody: file:/D:/Program/Maven/apache-maven-3.8.4-repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of okhttp3.RequestBody

翻译如下:

描述:



尝试调用一个不存在的方法。尝试从以下地点进行:



io.minio.S3Base。< clinit > (S3Base.java: 98)



以下方法不存在:



okhttp3.RequestBody.create ([BLokhttp3 / MediaType;) Lokhttp3 / RequestBody;



该方法的类okhttp3。RequestBody,可从以下位置获取:



jar:文件:/ D: /程序/ Maven / apache-maven-3.8.4-repository / com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar ! / okhttp3 / RequestBody.class



类层次结构是从以下位置加载的:



okhttp3。RequestBody:文件:/ D: /程序/ Maven / apache-maven-3.8.4-repository / com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar





行动:



修正应用程序的类路径,使其包含okhttp3的单一兼容版本。RequestBody

3. yml 配置文件

minio: 
 endpoint: http://127.0.0.1:9000
 accesskey: xxxx
 secretkey: xxxxxxxx
 bucketname: xxxx
 httppoint: http://127.0.0.1:9000

accesskey docker创建容器时创建的用户名
secretkey docker创建容器时创建的密码
bucketname 桶名,也就是minio服务器可以自由创建的一个一个根目录

4. MinioConfig 配置类

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

@Component
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
	/** 请求的 ip + port */
    private static String endpoint;
    
    /**访问的key**/
    private static String accesskey;
    
    /**访问的秘钥**/
    private static String secretkey;
    
    /**桶名**/
    private static String bucketname;
    
    
    /**http请求地址**/
    private static String httppoint;
    
    
    
	public static String getEndpoint() {
		return endpoint;
	}

	public void setEndpoint(String endpoint) {
		MinioConfig.endpoint = endpoint;
	}

	public static String getAccesskey() {
		return accesskey;
	}

	public void setAccesskey(String accesskey) {
		MinioConfig.accesskey = accesskey;
	}

	public static String getSecretkey() {
		return secretkey;
	}

	public void setSecretkey(String secretkey) {
		MinioConfig.secretkey = secretkey;
	}

	public static String getBucketname() {
		return bucketname;
	}

	public void setBucketname(String bucketname) {
		MinioConfig.bucketname = bucketname;
	}

	public static String getHttppoint() {
		return httppoint;
	}

	public void setHttppoint(String httppoint) {
		MinioConfig.httppoint = httppoint;
	}
}

5. MinioUtils 工具类

import com.alibaba.fastjson.JSONObject;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * 文件上传工具类
 *
 * @author eric
 * @Time 2021-11-06
 */

public class MinioUtils {

    private static Logger log = LoggerFactory.getLogger(MinioUtils.class);

    private static MinioClient minioClient;

    private static String endpoint;
    private static String bucketname;
    private static String accesskey;
    private static String secretkey;
    private static String httppoint;
    
    private static final String SEPARATOR = "/";

    
    // 使用main测试路径 2021-11-08 优化帮助类
//    public static void main(String[] args) {
//        FileUploadMinIoUtils fileUploadMinIoUtils=new FileUploadMinIoUtils("http://10.211.55.16:9000","leida","leida1234","leida1234");
//        try {
//            FileUploadMinIoUtils.putObject("leida","fdaf.png","/Users/eric/Desktop/12.png");
//        }catch (Exception e){
//
//        }
//    }

    {createMinioClient();}
    
	/**
     * 创建minioClient
     */
    public static void createMinioClient() {
    	endpoint = MinioConfig.getEndpoint();
        bucketname = MinioConfig.getBucketname();
        accesskey = MinioConfig.getAccesskey();
        secretkey = MinioConfig.getSecretkey();
        httppoint = MinioConfig.getSecretkey();
        try {
            if (null == minioClient) {
                log.info("minioClient create start");
                minioClient = MinioClient.builder().endpoint(endpoint).credentials(accesskey, secretkey)
                        .build();
                createBucket();
                log.info("minioClient create end");
            }
        } catch (Exception e) {
            log.error("连接MinIO服务器异常:{}", e);
        }
    }

    /**
     * 获取上传文件的基础路径
     *
     * @return url
     */
    public static String getBasisUrl() {
        return httppoint + SEPARATOR + bucketname + SEPARATOR;
    }


    /**
     * 初始化Bucket
     *操作存储桶
     * @throws Exception 异常
     */
    private static void createBucket()
            throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketname).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketname).build());
        }
    }

    /**
     * 验证bucketname是否存在
     *
     * @return boolean true:存在
     */
    public static boolean bucketExists()
            throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketname).build());
    }

    /**
     * 创建bucket
     *
     * @param bucketname bucket名称
     */
    public static void createBucket(String bucketname)
            throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketname).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketname).build());
        }
    }

    /**
     * 获取存储桶策略
     *
     * @param bucketname 存储桶名称
     * @return json
     */
    private JSONObject getBucketPolicy(String bucketname)
            throws IOException, InvalidKeyException, InvalidResponseException, BucketPolicyTooLargeException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InsufficientDataException, ErrorResponseException {
        String bucketPolicy = minioClient
                .getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketname).build());
        return JSONObject.parseObject(bucketPolicy);
    }

    /**
     * 获取全部bucket
     * 

* https://docs.minio.io/cn/java-client-api-reference.html#listBuckets */ public static List<Bucket> getAllBuckets() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient.listBuckets(); } /** * 根据bucketname获取信息 * * @param bucketname bucket名称 */ public static Optional<Bucket> getBucket(String bucketname) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketname)).findFirst(); } /** * 根据bucketname删除信息 * * @param bucketname bucket名称 */ public static void removeBucket(String bucketname) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketname).build()); } /** * 判断文件是否存在 * * @param bucketname 存储桶 * @param objectName 对象 * @return true:存在 */ public static boolean doesObjectExist(String bucketname, String objectName) { boolean exist = true; try { minioClient .statObject(StatObjectArgs.builder().bucket(bucketname).object(objectName).build()); } catch (Exception e) { exist = false; } return exist; } /** * 判断文件夹是否存在 * * @param bucketname 存储桶 * @param objectName 文件夹名称(去掉/) * @return true:存在 */ public static boolean doesFolderExist(String bucketname, String objectName) { boolean exist = false; try { Iterable<Result<Item>> results = minioClient.listObjects( ListObjectsArgs.builder().bucket(bucketname).prefix(objectName).recursive(false).build()); for (Result<Item> result : results) { Item item = result.get(); if (item.isDir() && objectName.equals(item.objectName())) { exist = true; } } } catch (Exception e) { exist = false; } return exist; } /** * 根据文件前置查询文件 * * @param bucketname bucket名称 * @param prefix 前缀 * @param recursive 是否递归查询 * @return MinioItem 列表 */ public static List<Item> getAllObjectsByPrefix(String bucketname, String prefix, boolean recursive) throws ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { List<Item> list = new ArrayList<>(); Iterable<Result<Item>> objectsIterator = minioClient.listObjects( ListObjectsArgs.builder().bucket(bucketname).prefix(prefix).recursive(recursive).build()); if (objectsIterator != null) { for (Result<Item> o : objectsIterator) { Item item = o.get(); list.add(item); } } return list; } /** * 获取文件流 * * @param bucketname bucket名称 * @param objectName 文件名称 * @return 二进制流 */ public static InputStream getObject(String bucketname, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient .getObject(GetObjectArgs.builder().bucket(bucketname).object(objectName).build()); } /** * 获取文件流 * * @param objectName 文件名称 * @return 二进制流 */ public static InputStream getObject( String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient .getObject(GetObjectArgs.builder().bucket(bucketname).object(objectName).build()); } /** * 断点下载 * * @param bucketname bucket名称 * @param objectName 文件名称 * @param offset 起始字节的位置 * @param length 要读取的长度 * @return 流 */ public InputStream getObject(String bucketname, String objectName, long offset, long length) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient.getObject( GetObjectArgs.builder().bucket(bucketname).object(objectName).offset(offset).length(length) .build()); } /** * 获取路径下文件列表 * * @param bucketname bucket名称 * @param prefix 文件名称 * @param recursive 是否递归查找,如果是false,就模拟文件夹结构查找 * @return 二进制流 */ public static Iterable<Result<Item>> listObjects(String bucketname, String prefix, boolean recursive) { return minioClient.listObjects( ListObjectsArgs.builder().bucket(bucketname).prefix(prefix).recursive(recursive).build()); } /** * 通过MultipartFile,上传文件 * @param file 文件 * @param objectName 对象名 */ public static ObjectWriteResponse putObject( MultipartFile file, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { InputStream inputStream = file.getInputStream(); return minioClient.putObject( PutObjectArgs.builder().bucket(bucketname).object(objectName).contentType(file.getContentType()) .stream( inputStream, inputStream.available(), -1) .build()); } /** * 通过MultipartFile,上传文件 * * @param bucketname 存储桶 * @param file 文件 * @param objectName 对象名 * @param contentType 如 image/png */ public static ObjectWriteResponse putObject(String bucketname, MultipartFile file, String objectName, String contentType) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { InputStream inputStream = file.getInputStream(); return minioClient.putObject( PutObjectArgs.builder().bucket(bucketname).object(objectName).contentType(contentType) .stream( inputStream, inputStream.available(), -1) .build()); } /** * 上传本地文件 * * @param bucketname 存储桶 * @param objectName 对象名称 * @param fileName 本地文件路径 */ public static ObjectWriteResponse putObject(String bucketname, String objectName, String fileName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient.uploadObject( UploadObjectArgs.builder() .bucket(bucketname).object(objectName).filename(fileName).build()); } /** * 上传本地文件 * * @param bucketname 存储桶 * @param objectName 对象名称 * @param fileName 本地文件路径 */ public static ObjectWriteResponse putObject(String objectName, String fileName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient.uploadObject( UploadObjectArgs.builder() .bucket(bucketname).object(objectName).filename(fileName).build()); } /** * 通过流上传文件 * * @param bucketname 存储桶 * @param objectName 文件对象 * @param inputStream 文件流 */ public static ObjectWriteResponse putObject(String bucketname, String objectName, InputStream inputStream) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient.putObject( PutObjectArgs.builder().bucket(bucketname).object(objectName).stream( inputStream, inputStream.available(), -1) .build()); } /** * 创建文件夹或目录 * * @param bucketname 存储桶 * @param objectName 目录路径 */ public static ObjectWriteResponse putDirObject(String bucketname, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient.putObject( PutObjectArgs.builder().bucket(bucketname).object(objectName).stream( new ByteArrayInputStream(new byte[]{}), 0, -1) .build()); } /** * 获取文件信息, 如果抛出异常则说明文件不存在 * * @param bucketname bucket名称 * @param objectName 文件名称 */ public static StatObjectResponse statObject(String bucketname, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient .statObject(StatObjectArgs.builder().bucket(bucketname).object(objectName).build()); } /** * 拷贝文件 * * @param bucketname bucket名称 * @param objectName 文件名称 * @param srcbucketname 目标bucket名称 * @param srcObjectName 目标文件名称 */ public static ObjectWriteResponse copyObject(String bucketname, String objectName, String srcbucketname, String srcObjectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { return minioClient.copyObject( CopyObjectArgs.builder() .source(CopySource.builder().bucket(bucketname).object(objectName).build()) .bucket(srcbucketname) .object(srcObjectName) .build()); } /** * 删除文件 * * @param bucketname bucket名称 * @param objectName 文件名称 */ public static void removeObject(String bucketname, String objectName) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException { minioClient .removeObject(RemoveObjectArgs.builder().bucket(bucketname).object(objectName).build()); } /** * 批量删除文件 * * @param bucketname bucket * @param keys 需要删除的文件列表 * @return */ public static void removeObjects(String bucketname, List<String> keys) { List<DeleteObject> objects = new LinkedList<>(); keys.forEach(s -> { objects.add(new DeleteObject(s)); try { removeObject(bucketname, s); } catch (Exception e) { log.error("批量删除失败!error:{}",e); } }); } /** * 将URLDecoder编码转成UTF8 * * @param str * @return * @throws UnsupportedEncodingException */ public static String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException { String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); return URLDecoder.decode(url, "UTF-8"); } public static String getEndpoint() { return endpoint; } public static String getBucketname() { return bucketname; } public static String getAccesskey() { return accesskey; } public static String getSecretkey() { return secretkey; } public static String getHttppoint() { return httppoint; } }

6. ObjectWriteResponse 上传后返回的对象

region() 方法可以获取上传后的服务端图片对应的完整访问路径

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