Minio整合SpringBoot

Minio整合SpringBoot


POM:
<dependency>
	<groupId>io.minio</groupId>
	<artifactId>minio</artifactId>
	<version>7.1.0</version>
</dependency>
yml文件配置(注意层级):
minio:
    bucket: "桶名"
    host: "http://192.168.1.123:5000"
    url: "${minio.host}/${minio.bucket}/"
    access-key: 用户名
    secret-key: 密码
将MinioClient作为Bean加入容器管理
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Item;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import static io.minio.ErrorCode.NO_SUCH_KEY;
import static io.minio.http.Method.GET;

@Component
public class MinioHelper {

	@Value(value = "${minio.bucket}")
	private String bucket;

	@Value(value = "${minio.host}")
	private String host;

	@Value(value = "${minio.url}")
	private String url;

	@Value(value = "${minio.access-key}")
	private String accessKey;

	@Value(value = "${minio.secret-key}")
	private String secretKey;

    @Autowired
    private MinioClient minioClient;

    @Bean
    public MinioClient getMinioClient() {
        MinioClient minioClient=MinioClient.builder()
            .endpoint(host).credentials(accessKey,secretKey).build();
        log.info("minioClient init success.");
        return minioClient;
    }
    private final Logger log = LoggerFactory.getLogger(MinioHelper.class);


    /**
     * 根据名字获得返回类型
     * @param fileName
     * @return
     * @throws Exception
     */
    public ObjectStat getStat(String fileName) throws Exception {
        ObjectStat stat = minioClient.statObject(StatObjectArgs.builder()
          .bucket(bucket).object(fileName).build());
        return stat;
    }

    /**
     *上传文件到桶中
     * @param multipartFile
     * @param directory should be end with / or ""
     * @return
     * @throws IOException
     * @throws InvalidKeyException
     * @throws ErrorResponseException
     * @throws IllegalArgumentException
     * @throws InsufficientDataException
     * @throws InternalException
     * @throws InvalidBucketNameException
     * @throws InvalidResponseException
     * @throws NoSuchAlgorithmException
     * @throws XmlParserException
     * @throws RegionConflictException
     * @throws ServerException
     */
    public String putObject(MultipartFile multipartFile, String directory) throws
        IOException, InvalidKeyException, ErrorResponseException, IllegalArgumentException,
        InsufficientDataException, InternalException, InvalidBucketNameException, InvalidResponseException,
        NoSuchAlgorithmException, XmlParserException, RegionConflictException, ServerException {
        log.debug("start upload file .");
        this.createBucket(minioClient, bucket);
        String fileName = multipartFile.getOriginalFilename();
        String rename = "";
        log.debug("Upload File name is:" + fileName);
        if (StringUtils.isNotEmpty(directory)) {
            rename = renameFileVersion(directory + "/" + fileName, minioClient);
        } else {
            rename = renameFileVersion(fileName, minioClient);
        }
        try (InputStream inputStream = multipartFile.getInputStream()) {
            minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(rename).
                contentType(multipartFile.getContentType()).
                stream(inputStream, multipartFile.getSize(), -1).build());
                inputStream.close();
            return rename;
        }
    }

   
    /**
     * 获取文件的InputStream流对象
     * @param fileUri format : directory/filename,filename must contains filetype,like xxx.pdf
     * @throws IOException
     * @throws InvalidKeyException
     * @throws IllegalArgumentException
     * @throws NoSuchAlgorithmException
     */
    public InputStream getFileInputStream(String fileUri) throws
        IOException, InvalidKeyException,IllegalArgumentException, NoSuchAlgorithmException {
        log.debug("start get file IO.");
        InputStream input=null;
        try {
             input=minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(fileUri).build());
        } catch(MinioException e) {
            log.debug("Error occurred: " + e.getMessage());
        }
        return input;
    }

    /**
     *在桶下创建文件夹,文件夹层级结构根据参数决定
     * @param WotDir should be end with /
     * @return
     * @throws IOException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws InsufficientDataException
     * @throws NoSuchAlgorithmException
     * @throws InternalException
     * @throws XmlParserException
     * @throws InvalidBucketNameException
     * @throws ErrorResponseException
     * @throws RegionConflictException
     * @throws ServerException
     */
    public String createDirectory(String WotDir) throws IOException, InvalidKeyException,
        InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException,
        InternalException, XmlParserException, InvalidBucketNameException,
        ErrorResponseException, RegionConflictException, ServerException {
        log.debug("start create directory.");
        this.createBucket(minioClient,bucket);
        minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(WotDir).stream(
            new ByteArrayInputStream(new byte[] {}), 0, -1)
            .build());
        log.debug("Create a new Directory:"+WotDir);
        return WotDir;
    }

    /**
     * 获取文件的下载url
     * @param fileUri
     * @return
     * @throws IOException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws InsufficientDataException
     * @throws NoSuchAlgorithmException
     * @throws ServerException
     * @throws InternalException
     * @throws XmlParserException
     * @throws InvalidBucketNameException
     * @throws ErrorResponseException
     * @throws RegionConflictException
     * @throws InvalidExpiresRangeException
     */

    public String getDownloadUrl(String fileUri) throws IOException, InvalidKeyException,
        InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException,
        ServerException,InternalException, XmlParserException, InvalidBucketNameException,
        ErrorResponseException, RegionConflictException,
        InvalidExpiresRangeException {
        log.debug("start get url for download.");
        this.createBucket(minioClient,bucket);
        //Use Get Method
        String fileurl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(this.bucket).object(fileUri).method(GET).build());
        log.debug("You can download file through this url:"+fileurl);
        return fileurl;
    }

    /**
     *该方法用于更新文档,
     * @param multipartFile
     * @param orderNum
     * @return 是Minio中的Object名
     * @throws IOException
     * @throws InvalidKeyException
     * @throws ErrorResponseException
     * @throws IllegalArgumentException
     * @throws InsufficientDataException
     * @throws InternalException
     * @throws InvalidBucketNameException
     * @throws InvalidResponseException
     * @throws NoSuchAlgorithmException
     * @throws XmlParserException
     * @throws RegionConflictException
     * @throws ServerException
     */
    public String uploadFileWithArgsForApp(MultipartFile multipartFile,String orderNum,String fileName) throws
        IOException, InvalidKeyException, ErrorResponseException, IllegalArgumentException,
        InsufficientDataException, InternalException, InvalidBucketNameException, InvalidResponseException,
        NoSuchAlgorithmException, XmlParserException, RegionConflictException, ServerException {
        log.debug("start upload file .");
        this.createBucket(minioClient,bucket);
        log.debug("Upload File name is:"+fileName);
        String rename=orderNum+"/"+fileName;
        try (InputStream inputStream = multipartFile.getInputStream()) {
            minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(rename).
                contentType(multipartFile.getContentType()).
                stream(inputStream,multipartFile.getSize(),-1).build());
            return rename;
        }
    }
    
    public String getloadUrl(String fileUri) throws IOException, InvalidKeyException,
        InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException,
        ServerException,InternalException, XmlParserException, InvalidBucketNameException,
        ErrorResponseException, RegionConflictException,
        InvalidExpiresRangeException {
        log.debug("start get url for download.");
        this.createBucket(minioClient,bucket);
        //Use Get Method
        String fileurl = minioClient.getObjectUrl(bucket,fileUri);
        log.debug("You can download file through this url:"+fileurl);
        return fileurl;
    }

    /**
     * 批量下载
     * @param directory
     * @return
     * @throws IOException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws InsufficientDataException
     * @throws NoSuchAlgorithmException
     * @throws ServerException
     * @throws InternalException
     * @throws XmlParserException
     * @throws InvalidBucketNameException
     * @throws ErrorResponseException
     * @throws InvalidExpiresRangeException
     */
    public List<String> downLoadMore(String directory) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException, InvalidExpiresRangeException {
        Iterable<Result<Item>> objs = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucket).prefix(directory).useUrlEncodingType(false).build());
        List<String> list =new ArrayList<>();
        for (Result<Item> result : objs) {
            String objectName = null;
            objectName = result.get().objectName();
            ObjectStat statObject = minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(objectName).build());
            if (statObject != null && statObject.length() > 0) {
                String fileurl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(this.bucket).object(statObject.name()).method(GET).build());
                list.add(fileurl);
            }
        }
        return list;
    }

    /**
     * 刪除文件
     * @param fileUri
     * @return
     * @throws IOException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws InsufficientDataException
     * @throws NoSuchAlgorithmException
     * @throws ServerException
     * @throws InternalException
     * @throws XmlParserException
     * @throws InvalidBucketNameException
     * @throws ErrorResponseException
     */
    public  String removeFile(String fileUri) throws IOException, InvalidKeyException, InvalidResponseException,
       InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException,
       InvalidBucketNameException, ErrorResponseException {
       log.debug("Start remove File :"+fileUri);
       ObjectStat objectStat = minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(fileUri).build());
       minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(fileUri).build());
       log.debug("File has been removed");
       return fileUri;

   }

    /**
     * 合并PDF
     * @param files
     * @param dir
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws IOException
     * @throws InsufficientDataException
     * @throws InternalException
     * @throws InvalidResponseException
     * @throws InvalidBucketNameException
     * @throws XmlParserException
     * @throws ServerException
     * @throws ErrorResponseException
     */
    public String mergeFile(List<String> files, String dir,String name) throws NoSuchAlgorithmException, InvalidKeyException, IOException, InsufficientDataException, InternalException, InvalidResponseException, InvalidBucketNameException, XmlParserException, ServerException, ErrorResponseException {
        OutputStream outputStream = new ByteArrayOutputStream();
        PDFMergerUtility merger = new PDFMergerUtility();
        merger.setDestinationStream(outputStream);
        for (String s:files
             ) {
            InputStream in = this.getFileInputStream(s);
            merger.addSource(in);//添加所有文件的输入流对象
        }
        merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
        log.debug("Merge File Stream success" );
        ByteArrayOutputStream baos = (ByteArrayOutputStream) merger.getDestinationStream();
        ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
        MultipartFile multipartFile = new MockMultipartFile(name+".pdf", name+".pdf", "application/pdf", IOUtils.toByteArray(swapStream));
        log.debug("Merge upload File has been create" );
        String fileName = multipartFile.getOriginalFilename();
        String rename = dir+"/"+fileName;
        try (InputStream inputStream = multipartFile.getInputStream()) {
            minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(rename).
                contentType(multipartFile.getContentType()).
                stream(inputStream, multipartFile.getSize(), -1).build());
            inputStream.close();
            return rename;
        }

    }

    /**
     * 重命名
     * @param objectName
     * @param minioClient
     * @return
     * @throws IOException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws InsufficientDataException
     * @throws NoSuchAlgorithmException
     * @throws ServerException
     * @throws XmlParserException
     * @throws InvalidBucketNameException
     * @throws InternalException
     * @throws ErrorResponseException
     */
    private String renameFileVersion(String objectName,MinioClient minioClient) throws IOException, InvalidKeyException
        , InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, XmlParserException,
        InvalidBucketNameException, InternalException, ErrorResponseException {
        log.debug("start rename file.");
        boolean flag =false;
        int i=2;
        StringBuffer temp = new StringBuffer(objectName.substring(0, objectName.length() - 4));
        String result = objectName;
        String sufix = objectName.substring(objectName.length() - 4);
        String version = objectName.substring(objectName.length() - 7,objectName.length() - 4);
        if(version.startsWith("_V")){//存在有版本号的,非初始版本
            do{
                try {
                    ObjectStat objectStat = minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(result).build());
                    temp=new StringBuffer(objectName.substring(0, objectName.length() - 7));
                    temp.append("_V"+i+sufix);
                    result = temp.toString();
                    i++;
                    flag = true;
                } catch (ErrorResponseException e) {
                    if(e.errorResponse().errorCode().equals(NO_SUCH_KEY)){
                        flag=false;
                    }else throw e ;
                }
            }while (flag);
        }else{
            do{
                try {
                    ObjectStat objectStat = minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(result).build());
                    //每次上传的版本不能低于上一个版本
                    //第一次上传不加版本号
                    //第二次上传为v2,依次叠加,后续上传规则变更,另作修改
                    if (i>2){
                        temp=new StringBuffer(objectName.substring(0, objectName.length() - 4));
                    }
                    temp.append("_V"+i+sufix);
                    result = temp.toString();
                    i++;
                    flag = true;
                } catch (ErrorResponseException e) {
                    if(e.errorResponse().errorCode().equals(NO_SUCH_KEY)){
                        flag=false;
                    }else throw e ;
                }
            }while (flag);
        }


        return result;
    }
/*创建桶*/
    private void createBucket(MinioClient minioClient,String bucket) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException, RegionConflictException {
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
            log.debug("Create a new Bucket:"+bucket);
        }else{
            log.debug("Bucket has been exisit:"+bucket);
        }
    }
}

posted @ 2021-03-01 14:05  陌客丁  阅读(1937)  评论(2编辑  收藏  举报