SpringBoot整合MinIO实现文件的上传下载以及获取预览URL
创始人
2024-11-10 08:11:01

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;     } 

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...