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

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中添加

主要的依赖:

		<dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.5.7</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>3.2.1</version>
        </dependency>

其它依赖:

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-configuration-processor -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>3.2.4</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.14.0</version>
        </dependency>

配置文件

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;
    }
  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
实现Spring Boot整合MinIO实现多级目录下文件的下载,可以按照以下步骤进行: 1. 引入MinIO的依赖 在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>7.1.0</version> </dependency> ``` 2. 配置MinIO连接信息 在application.yml文件中添加以下配置信息: ```yaml minio: endpoint: http://localhost:9000 # MinIO服务地址 accessKey: minioadmin # 访问Key secretKey: minioadmin # 访问Secret bucketName: test-bucket # 存储桶名称 ``` 3. 创建MinIO客户端 创建MinIO客户端的代码如下: ```java @Configuration public class MinioConfig { @Value("${minio.endpoint}") private String endpoint; @Value("${minio.accessKey}") private String accessKey; @Value("${minio.secretKey}") private String secretKey; @Value("${minio.bucketName}") private String bucketName; @Bean public MinioClient minioClient() throws InvalidPortException, InvalidEndpointException { return MinioClient.builder() .endpoint(endpoint) .credentials(accessKey, secretKey) .build(); } @Bean public String bucketName() { return bucketName; } } ``` 4. 实现文件下载接口 实现文件下载接口的代码如下: ```java @RestController @RequestMapping("/file") public class FileController { @Autowired private MinioClient minioClient; @Autowired private String bucketName; @GetMapping("/download") public ResponseEntity<Resource> downloadFile(@RequestParam("path") String path) throws Exception { String[] pathArr = path.split("/"); String objectName = pathArr[pathArr.length - 1]; String objectPath = path.substring(0, path.lastIndexOf("/") + 1); InputStream inputStream = minioClient.getObject(GetObjectArgs.builder() .bucket(bucketName) .object(objectPath + objectName) .build()); ByteArrayResource resource = new ByteArrayResource(inputStream.readAllBytes()); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + objectName + "\"") .body(resource); } } ``` 其中,`path`参数是要下载的文件路径,例如:`folder1/folder2/test.txt`。 5. 测试文件下载接口 启动应用程序后,访问`http://localhost:8080/file/download?path=folder1/folder2/test.txt`即可下载名为`test.txt`的文件,该文件位于MinIO存储桶的`folder1/folder2/`路径下。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值