springBoot整合minio

2023-09-22 14:51:38
<minio.version>8.3.4</minio.version>
<!-- 其它 && 数据源加密 -->
        <org.bouncycastle.bcprov-jdk15on.version>1.70</org.bouncycastle.bcprov-jdk15on.version>
<dependencies>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>${minio.version}</version>
        </dependency>
        <!-- 数据源加解密 -->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>${org.bouncycastle.bcprov-jdk15on.version}</version>
        </dependency>
        <!--错误:springboot 配置顶上爆红-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

import com.sunyard.staging.starter.minio.utils.AesCbcUtil;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Setter
@Getter
@Configuration
@ConfigurationProperties(prefix = "spring.minio")
public class MinioConfig {
    //地址 http://172.1.0.79:9000
    private String endpoint;
    //minio账号
    private String accessKey;
    //minio密码
    private String secretKey;

    /**
     * 初始化minio连接池
     * @return MinioClient
     */
    @Bean
    public io.minio.MinioClient minioClient(){
        return io.minio.MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, AesCbcUtil.Decrypt(secretKey))
                .build();
    }
}


import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MinioService {

    @Resource
    private MinioClient minioClient;

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

    /**
     * 创建存储bucket
     * @param bucketName
     * @return Boolean
     */
    public Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            log.error("创建存储bucket出现异常",e);
            return false;
        }
        return true;
    }
    /**
     * 删除存储bucket
     * @param bucketName
     * @return Boolean
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            log.error("删除存储bucket出现异常",e);
            return false;
        }
        return true;
    }
    /**
     * 获取全部bucket
     */
    public List<Bucket> getAllBuckets() {
        try {
            return minioClient.listBuckets();
        } catch (Exception e) {
            log.error("获取全部bucket出现异常",e);
        }
        return null;
    }

    /**
     * 文件上传
     * @param file 文件
     * @param bucketName
     * @return Boolean
     */
    public Boolean upload(MultipartFile file,String bucketName) {
        // 修饰过的文件名 非源文件名
        String fileName = "2021-07/21/";
        fileName = fileName+file.getOriginalFilename();
        try {
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName)
                    .stream(file.getInputStream(),file.getSize(),-1).contentType(file.getContentType()).build();
            //文件名称相同会覆盖
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            log.error("文件上传出现异常",e);
            return false;
        }
        return true;
    }

    /**
     * 预览图片
     * @param fileName
     * @param bucketName
     * @return
     */
    public String preview(String fileName,String bucketName){
        // 查看文件地址
        GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(bucketName).object(fileName).method(Method.GET).build();
        try {
            String url = minioClient.getPresignedObjectUrl(build);
            return url;
        } catch (Exception e) {
            log.error("预览图片出现异常",e);
        }
        return null;
    }

    /**
     * 文件下载
     * @param fileName 文件名称
     * @param res response
     * @param bucketName
     * @return Boolean
     */
    public void download(String fileName, HttpServletResponse res, String bucketName) {
        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) {
            log.error("文件下载出现异常",e);
        }
    }

    /**
     * 查看文件对象
     * @param bucketName
     * @return 存储bucket内文件对象信息
     */
    public List<Item> listObjects(String bucketName) {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        List<Item> items = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                items.add(result.get());
            }
        } catch (Exception e) {
            log.error("查看文件对象出现异常",e);
            return null;
        }
        return items;
    }

    /**
     * 删除
     * @param fileName
     * @param bucketName
     * @return
     * @throws Exception
     */
    public boolean remove(String fileName,String bucketName){
        try {
            minioClient.removeObject( RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());
        }catch (Exception e){
            log.error("删除文件出现异常",e);
            return false;
        }
        return true;
    }

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


import com.google.common.io.FileBackedOutputStream;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@Component
public class MinioUtil {

    @Resource
    private MinioClient minioClient;

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

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

    public Boolean makeFolderPath( String folderPath) {
        try {
            folderPath = folderPath.substring(folderPath.indexOf('/'));
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(constantBucket).object(folderPath).stream(new ByteArrayInputStream(new byte[]{}), 0, -1)
                    .build());
        } catch (Exception e) {
            return false;
        }
        return true;
    }

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

    /**
     * 获取全部bucket
     */
    public List<Bucket> getAllBuckets() {
        try {
            return minioClient.listBuckets();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 文件上传
     *
     * @param file       文件
     * @param bucketName
     * @return Boolean
     */
    public Boolean upload(MultipartFile file, String bucketName, String fileName) {
        // 修饰过的文件名 非源文件名
        /*String fileName = "2021-07/21/";
        fileName = fileName+file.getOriginalFilename();*/
        try {
            fileName = fileName.substring(fileName.indexOf('/'));
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            //文件名称相同会覆盖
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    public boolean uploadBypath(MultipartFile file,  String filePath, String fileName) {
        try {
            String path = filePath + fileName;
            path = path.substring(path.indexOf('/'));
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(constantBucket).object(path)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            minioClient.putObject(objectArgs);
        } catch (Exception e) {
            return false;
        }
        return true;
    }


    /**
     * 预览图片
     *
     * @param fileName
     * @param bucketName
     * @return
     */
    public String preview(String fileName, String bucketName) {
        // 查看文件地址
        GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(bucketName).object(fileName).method(Method.GET).build();
        try {
            String url = minioClient.getPresignedObjectUrl(build);
            return url;
        } catch (Exception e) {
            return "查看失败";
        }
    }

    /**
     * 文件下载
     *
     * @param fileName   文件名称
     * @param res        response
     * @return Boolean
     */
    public String download(String fileName, HttpServletResponse res) {
        GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(constantBucket)
                .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();
                }
            }
            return "downloadSuccess";
        } catch (Exception e) {
            return "downloadFailed";
        }
    }

    /**
     * 批量下载某个文件下的所有文件 以压缩包的方式进行下载
     *
     * @param filePath
     * @param res
     **/
    @SneakyThrows
    public String downloadByPath(String filePath, HttpServletResponse res) {
        Iterable<Result<Item>> myObjects;
        myObjects = minioClient.listObjects(ListObjectsArgs.builder()
                .bucket(constantBucket)
                .prefix(filePath)
                .recursive(true)
                .build());
        List<String> filePaths = new ArrayList<>();
        for (Result<Item> result : myObjects) {
            Item item = result.get();
            filePaths.add(item.objectName());
        }
        ZipOutputStream zipos = null;
        DataOutputStream os = null;
        InputStream is = null;
        try {
            res.reset();
            String zipName = new String(URLEncoder.encode("test", "UTF-8").getBytes(), StandardCharsets.ISO_8859_1);
            res.setHeader("Content-Disposition", "attachment;fileName=\"" + zipName + ".zip\"");
            zipos = new ZipOutputStream(new BufferedOutputStream(res.getOutputStream()));
            zipos.setMethod(ZipOutputStream.DEFLATED);
            for (int i = 0; i < filePaths.size(); i++) {
                String file = filePaths.get(i);
                String packageName = filePaths.get(i).replace(filePath + "/", "");
                try {
                    zipos.putNextEntry(new ZipEntry(packageName));
                    os = new DataOutputStream(zipos);
                    is = minioClient.getObject(GetObjectArgs.builder().bucket(constantBucket).object(file).build());
                    byte[] b = new byte[1024];
                    int length = 0;
                    while ((length = is.read(b)) != -1) {
                        os.write(b, 0, length);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            is.close();
            os.flush();
            os.close();
            zipos.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (zipos != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return "downloadSucess";
    }


    /**
     * 查看文件对象
     *
     * @param bucketName
     * @return 存储bucket内文件对象信息
     */
    public List<Item> listObjects(String bucketName) {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        List<Item> items = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                items.add(result.get());
            }
        } catch (Exception e) {
            return null;
        }
        return items;
    }


    /**
     * 查看文件目录下的文件对象
     *
     *
     * @param filePath
     * @return 文件目录下文件对象信息
     */

    public List<Item> listFileObjects( String filePath) {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder()
                        .bucket(constantBucket)
                        .prefix(filePath)
                        .recursive(true).build()
        );
        List<Item> items = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                items.add(result.get());
            }
        } catch (Exception e) {
            return null;
        }
        return items;
    }


    /**
     * 删除
     *
     * @param fileName
     * @return
     * @throws Exception
     */
    public boolean remove(String fileName) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(constantBucket).object(fileName).build());
        } catch (Exception e) {
            return false;
        }
        return true;
    }

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


    /**
     * 递归删除制定文件路径下的所有文件和文件夹
     * @param minioPath  文件路径
     */
    @SneakyThrows
    public boolean removeMedFile( String minioPath) {
        minioPath = minioPath.substring(minioPath.indexOf('/') + 1);
        Iterable<Result<Item>> listResults = minioClient.listObjects(
                ListObjectsArgs.builder()
                        .bucket(constantBucket)
                        .prefix(minioPath)
                        .recursive(true).build()
        );
        List<DeleteObject> objects = new LinkedList<>();
        for (Result<Item> listResult : listResults) {
            Item item = listResult.get();
            String itemName = item.objectName().toString();
            System.out.println(itemName);
            objects.add(new DeleteObject(itemName));
        }
        Iterable<Result<DeleteError>> results =
                minioClient.removeObjects(
                        RemoveObjectsArgs.builder()
                                .bucket(constantBucket)
                                .objects(objects).build()
                );
        for (Result<DeleteError> result : results) {
            DeleteError error = result.get();
            System.out.println(error.objectName());
        }
        return true;
    }

    @SneakyThrows
    public boolean copyMedFile( String srcfilePath, String trgfilePath) {
        try{
            minioClient.copyObject(
                    CopyObjectArgs.builder()
                            .bucket(constantBucket)
                            .object(trgfilePath)
                            .source(
                                    CopySource.builder()
                                            .bucket(constantBucket)
                                            .object(srcfilePath)
                                            .build())
                            .build());
        } catch(Exception e){
            return false ;
        }
        return true ;
    }

    @SneakyThrows
    public StatObjectResponse getAttachmentInfo( String filePath){
        try{
            StatObjectResponse statObjectResponse = minioClient.statObject(StatObjectArgs.builder()
                    .bucket(constantBucket)
                    .object(filePath).build()) ;
            return statObjectResponse ;
        }catch(Exception e){
            return null ;
        }
    }
}
更多推荐

springboot和vue:五、RESTful服务+HTTP状态码+swagger配置

RESTfulRESTful的特点每一个URI代表一种资源客户端使用GET、POST、PUT、DELETE四种表示操作方式的动词对服务端资源进行操作:POST用于新建资源(也可以用于更新资源),PUT用于更新资源资源的表现形式是JSON或者HTML。客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请

安全厂商安恒信息加入龙蜥社区,完成 与 Anolis OS 兼容适配

近日,杭州安恒信息技术股份有限公司(以下简称“安恒信息”)签署了CLA(ContributorLicenseAgreement,贡献者许可协议),正式加入龙蜥社区(OpenAnolis),并成为龙蜥社区安全联盟(OASA)首批成员单位。安恒信息于2007年创立,秉承着企业使命“构建安全可信的数字世界”,将数字经济安全视

自己动手写数据库:关系代数和查询树执行效率的推导

上几节我们完成了sql解释器的实现。通过解析sql语句,我们能知道sql语句想做什么,接下来就需要执行sql语句的意图,也就是从给定表中抽取所所需要的数据。要执行sql语句,我们需要了解所谓的“关系代数”,所谓代数本质上就是定义操作符和操作对象,在关系代数里,操作符有三种,分别为select,project和produ

什么是BI报表?

文章目录出现背景BI商务智能报表BI和报表的区别从功能看从平台看从开发过程看BI报表的好处出现背景对现代企业而言,数据分析的重要性已越来越明显。但对于日渐复杂的数据来说,使用excel处理已然不能满足解决问题的需要,同时效率也不高,于是诞生了BI,businessintelligence商务智能,也相应出现了报表。BI

RS485以及MODBUS学习

学习目的:1、什么是485?2、485如何通信?3、如何使用熟能生巧?RS485是一种四总线通信,分别是VCC、GND、485_A、485_B。两根负责通信,两根负责进行供电。RS485通信硬件层:解决的是数据传输问题,也就是如何将“0”和“1”传输到另外一端设备。软件层:ModBus协议则是解决数据传输的含义和意义那

云原生架构

云原生架构一、Docker1.1镜像仓库dockerhub1.2镜像操作下载:dockerpull镜像(nginx、redis)直接下载是该工具的最新版本,可以指定通过镜像名:版本来指定版本。删除:dockerrmi镜像名:版本号(默认lastest)/镜像id1.3容器操作1.3.1运行镜像:dockerrun[op

Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单

项目说明随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及审计监督要求;通过电子化平台提高招投标工作的公开性和透明性;通过电子化招投标,使得招标采购的质量更高、速度

Linux内核顶层Makefile的make过程总结

一.Linux内核源码的make编译本文对Linux内核源码的make时,顶层Makefile所做的事进行总结。即总结一下Linux内核源码的make过程。本文续上一篇文章,地址如下:Linux内核顶层Makefile的make过程说明二_凌肖战的博客-CSDN博客二.Linux的make过程总结之前几篇文章,分析了L

Pikachu Burte Force(暴力破解)

一、BurteForce(暴力破解)概述​“暴力破解”是一攻击具手段,在web攻击中,一般会使用这种手段对应用系统的认证信息进行获取。其过程就是使用大量的认证信息在认证接口进行尝试登录,直到得到正确的结果。为了提高效率,暴力破解一般会使用带有字典的工具来进行自动化操作。​理论上来说,大多数系统都是可以被暴力破解的,只要

【Vue】快速入门和生命周期

目录前言一、vue的介绍1.Vue.js是什么?2.库和框架的区别3.基本概念和用法:二、MVVM的介绍1.什么是MVVM?2.MVVM的组成部分3.MVVM的工作流程4.MVVM的优势5.MVVM的应用场景三、vue实例1.模板语法:2.双向数据绑定3.虚拟dom实例四、vue生命周期钩子总结前言Vue.js是一款流

数据在C++中的大小(占用内存)

C++中的大小(占用内存)摘要正文获取数据类型的大小注意结论摘要在C++中,了解数据类型的大小及其在内存中的占用情况对于编写高效的代码至关重要。本文将介绍C++中不同数据类型的大小以及如何计算它们所占用的内存空间。正文在C++中,每个数据类型都有不同的字节大小,这取决于编译器和操作系统的实现。下面是一些常见的数据类型及

热文推荐