SpringBoot整合MinIO实现文件的上传下载以及获取预览URL

2024-06-04 6127阅读

SpringBoot整合MinIO实现文件的上传下载以及获取预览URL

JDK17 SpringBoot3

参考 https://min.io/docs/minio/linux/developers/java/API.html?ref=docs-redirect#uploadObject

源码 https://gitee.com/Uncommen/easy-min-io

引入依赖

pom.xml中添加

主要的依赖:

		
            io.minio
            minio
            8.5.7
        
        
            org.springframework.boot
            spring-boot-starter
        
        
            org.springframework.boot
            spring-boot-starter-web
            3.2.1
        

其它依赖:

		
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
        
            org.springframework.boot
            spring-boot-configuration-processor
            3.2.4
        
        
        
            org.projectlombok
            lombok
            1.18.30
            provided
        
        
        
            org.apache.commons
            commons-lang3
            3.14.0
        

配置文件

application.yml中添加minio相关配置:

minio:
  endpoint: http://localhost:9000 
  accessKey: Y1zXHmjPZHIf2R8Rp2jM
  secretKey: nz8LdzSb3Defz1Gqs2UB9HAjBcpeRoiDiYZ1kLXE
  bucketName: easy
  • endpoint:MinIO服务器的地址
  • accesskey:MinIO生成的accessKey
  • secretKey:MinIO生成的secretKey
  • bucketName:桶名(如果桶名不固定,可以在代码中更改而不在这里写***)

    属性类

    提供一个MinIO属性类以便与配置文件进行映射:

    MinIOProperty.java

    /**
     * MinIO 存储属性类
     *
     * @author Uncommon
     */
    @Data
    @Configuration
    @ConfigurationProperties(prefix = "minio")
    public class MinIOProperty {
        // MinIO地址
        private String endpoint;
        // MinIO accessKey
        private String accessKey;
        // MinIO secretKey
        private String secretKey;
        // MiniO桶名称
        private String bucketName;
    }
    

    配置类

    用于初始化MinIO配置

    MinIOConfig.java

    /**
     * MinIO配置类
     *
     * @author Uncommon
     */
    @Configuration
    public class MinioConfig {
        @Resource
        private MinIOProperty minioProperty;
        /**
         * 初始化minio配置
         */
        @Bean
        public MinioClient minioClient() {
            return MinioClient.builder()
                    .endpoint(minioProperty.getEndpoint()) //操作MinIO地址
                    .credentials(minioProperty.getAccessKey(), minioProperty.getSecretKey())
                    .build();
        }
    }
    

    具体代码逻辑实现

    上传文件

    MinIOService.java

    /**
         * 上传文件
         *
         * @param file 文件
         * @return 文件名
         */
        String uploadFile(MultipartFile file);
    

    MinIOServiceImpl.java

        /**
         * 上传文件
         *
         * @param file 文件
         * @return 文件名
         */
        @Override
        public String uploadFile(MultipartFile file) {
            // 获取桶名
            String bucketName = minioProperty.getBucketName();
            log.info("开始向桶 {} 上传文件", bucketName);
            //给文件生成一个唯一名称  当日日期-uuid.后缀名
            String folderName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"));
            String fileName = String.valueOf(UUID.randomUUID());
            String extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));//文件后缀名
            String objectName = folderName + "-" + fileName + extName;
            InputStream inputStream;
            try {
                inputStream = file.getInputStream();
                // 配置参数
                PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(objectName)
                        .stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build();
                //文件名称相同会覆盖
                minioClient.putObject(objectArgs);
            } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                     InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |
                     XmlParserException e) {
                log.error("文件上传失败: " + e);
                throw new RuntimeException(e);
            }
            log.info("文件上传成功,文件名为:{}", objectName);
            return objectName;
        }
    

    下载文件

    MinIOService.java

        /**
         * 下载文件
         *
         * @param fileName 文件名
         * @param response HttpServletResponse
         */
        void downloadFile(String fileName, HttpServletResponse response);
    

    MinIOServiceImpl.java

       /**
         * 下载文件
         *
         * @param fileName 文件名
         * @param response HttpServletResponse
         */
        @Override
        public void downloadFile(String fileName, HttpServletResponse response) {
            // 获取桶名
            String bucketName = minioProperty.getBucketName();
            if (StringUtils.isBlank(fileName)) {
                log.error("文件名为空!");
                return;
            }
            try {
                // 获取文件流
                InputStream file = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
                response.reset();
                response.setHeader("Content-Disposition", "attachment;filename=" +
                        URLEncoder.encode(fileName.substring(fileName.lastIndexOf("/") + 1), StandardCharsets.UTF_8));
                response.setContentType("application/octet-stream");
                response.setCharacterEncoding("UTF-8");
                // 获取输出流
                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();
                log.info("文件{}下载成功", fileName);
            } catch (Exception e) {
                log.error("文件名: " + fileName + "下载文件时出现异常: " + e);
            }
        }
    

    删除文件

    MinIOService.java

      /**
         * 删除文件
         *
         * @param fileName 文件名
         */
        void deleteFile(String fileName);
    

    MinIOServiceImpl.java

        /**
         * 删除文件
         *
         * @param fileName 文件名
         */
        @Override
        public void deleteFile(String fileName) {
            // 获取桶名
            String bucketName = minioProperty.getBucketName();
            try {
                if (StringUtils.isBlank(fileName)) {
                    log.error("删除文件失败,文件名为空!");
                    return;
                }
                // 判断桶是否存在
                boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
                // 桶存在
                if (isExist) {
                    minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());
                } else { // 桶不存在
                    log.error("删除文件失败,桶{}不存在", bucketName);
                }
            } catch (Exception e) {
                log.error("删除文件时出现异常: " + e.getMessage());
            }
        }
    

    获取文件预览URL

    MinIOService.java

        /**
         * 获取文件预览url
         *
         * @param fileName 文件名
         * @return
         */
        String getPresignedUrl(String fileName);
    

    MinIOServiceImpl.java

        /**
         * 获取文件预览url
         *
         * @param fileName 文件名
         * @return 文件预览url
         */
        @Override
        public String getPresignedUrl(String fileName) {
            // 获取桶名
            String bucketName = minioProperty.getBucketName();
            String presignedUrl = null;
            try {
                if (StringUtils.isBlank(fileName)) {
                    log.error("获取文件预览url失败,文件名为空!");
                    return presignedUrl;
                }
                // 判断桶是否存在
                boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
                // 桶存在
                if (isExist) {
                    presignedUrl = minioClient.getPresignedObjectUrl(
                            GetPresignedObjectUrlArgs.builder()
                                    .method(Method.PUT)
                                    .bucket(bucketName)
                                    .object(fileName)
                                    .expiry(1, TimeUnit.DAYS) // 一天过期时间
                                    .build());
                    return presignedUrl;
                } else {  // 桶不存在
                    log.error("获取文件预览url失败,桶{}不存在", bucketName);
                }
            } catch (Exception e) {
                log.error("获取文件预览url时出现异常: " + e.getMessage());
            }
            return presignedUrl;
        }
    

    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]