《SpringBoot2.0 实战》系列-整合MinIo实现文件上传、下载

MinIo简介

MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。

MinIO官方文档:https://docs.min.io/cn/

安装

  • docker 安装:
docker run -p 9000:9000 --name minio1 \
  -e "MINIO_ACCESS_KEY=gourd.hu" \
  -e "MINIO_SECRET_KEY=gourd123456" \
  -v /mnt/data:/data \
  -v /mnt/config:/root/.minio \
  minio/minio server /data
  • docker-compose 安装:
version: '3.3'
services:
  # minio
  minio:
    image: minio/minio
    container_name: minio
    hostname: minio
    command: server /data
    restart: always
    ports:
      - "9000:9000"
    volumes:
      - /home/gourd/minio/data:/data
      - /home/gourd/minio/config:/root/.minio
    environment:
    	# 配置域名或者公网IP端口。
      - MINIO_DOMAIN=http://111.231.111.150:9000
      - MINIO_ACCESS_KEY=gourd.hu
      - MINIO_SECRET_KEY=gourd123456

注意:

MINIO_SECRET_KEY密钥必须大于8位,否则会创建失败

管理后台

安装完之后,可登录管理后台查看文件、修改密码等。

地址: 你配置的MINIO_DOMAIN
账号: 默认你配置的MINIO_ACCESS_KEY
密码: 默认你配置的MINIO_SECRET_KEY

在这里插入图片描述

springboot整合

pom.xml中引入MinIO依赖
<!--minio-->
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.0.1</version>
</dependency>
application.yml中配置MinIO
# MinIo文件服务器
min:
  io:
    endpoint: http://111.231.111.150:9000
    accessKey: gourd.hu
    secretKey: gourd123456
核心类

minio配置属性类

/**
 * minio配置属性
 *
 * @author gourd.hu
 */
@Data
@ConfigurationProperties(prefix = "min.io")
public class MinIoProperties {
    /**
     * Minio 服务地址
     */
    private String endpoint;

    /**
     * Minio ACCESS_KEY
     */
    private String accessKey;

    /**
     * Minio SECRET_KEY
     */
    private String secretKey;
}

minio工具类,列出了常用的文件操作,如需其他的操作,需要参看官网java-api文档:https://docs.min.io/cn/java-client-api-reference.html

/**
 * minio工具类
 *
 * @author gourd.hu
 */
@Configuration
@EnableConfigurationProperties({MinIoProperties.class})
public class MinIoUtil {
    private MinIoProperties minIo;
    public MinIoUtil(MinIoProperties minIo) {
        this.minIo = minIo;
    }
    private static MinioClient minioClient;
    @PostConstruct
    public void init() {
        try {
            minioClient = MinioClient.builder()
                    .endpoint(minIo.getEndpoint())
                    .credentials(minIo.getAccessKey(), minIo.getSecretKey())
                    .build();
        } catch (Exception e) {
            ResponseEnum.MIN_IO_INIT_FAIL.assertFail(e);
        }
    }

    /**
     * 判断 bucket是否存在
     *
     * @param bucketName
     * @return
     */
    public static boolean bucketExists(String bucketName) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            ResponseEnum.MIN_IO_BUCKET_CHECK_FAIL.assertFail(e);
        }
        return false;
    }

    /**
     * 判断 bucket是否存在
     *
     * @param bucketName
     * @param region
     * @return
     */
    public static boolean bucketExists(String bucketName, String region) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).region(region).build());
        } catch (Exception e) {
            ResponseEnum.MIN_IO_BUCKET_CHECK_FAIL.assertFail(e);
        }
        return false;
    }

    /**
     * 创建 bucket
     *
     * @param bucketName
     */
    public static void makeBucket(String bucketName) {
        try {
            boolean isExist = bucketExists(bucketName);
            if (!isExist) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            ResponseEnum.MIN_IO_BUCKET_CREATE_FAIL.assertFail(e);
        }
    }

    /**
     * 创建 bucket
     *
     * @param bucketName
     * @param region
     */
    public static void makeBucket(String bucketName, String region) {
        try {
            boolean isExist = bucketExists(bucketName, region);
            if (!isExist) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).region(region).build());
            }
        } catch (Exception e) {
            ResponseEnum.MIN_IO_BUCKET_CREATE_FAIL.assertFail(e);
        }
    }

    /**
     * 删除 bucket
     *
     * @param bucketName
     * @return
     */
    public static void deleteBucket(String bucketName) {
        try {
            minioClient.deleteBucketEncryption(
                    DeleteBucketEncryptionArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            ResponseEnum.MIN_IO_BUCKET_DELETE_FAIL.assertFail(e);
        }
    }

    /**
     * 删除 bucket
     *
     * @param bucketName
     * @return
     */
    public static void deleteBucket(String bucketName, String region) {
        try {
            minioClient.deleteBucketEncryption(
                    DeleteBucketEncryptionArgs.builder().bucket(bucketName).bucket(region).build());
        } catch (Exception e) {
            ResponseEnum.MIN_IO_BUCKET_DELETE_FAIL.assertFail(e);
        }
    }

    /**
     * 文件上传
     *
     * @param bucketName
     * @param objectName
     * @param filePath
     */
    public static void uploadObject(String bucketName, String objectName, String filePath) {
        putObject(bucketName, null, objectName, filePath);
    }

    /**
     * 文件上传
     *
     * @param bucketName
     * @param objectName
     * @param filePath
     */
    public static void uploadObject(String bucketName, String region, String objectName, String filePath) {
        putObject(bucketName, region, objectName, filePath);
    }

    /**
     * 文件上传
     *
     * @param multipartFile
     * @param bucketName
     * @return
     */
    public static String uploadObject(MultipartFile multipartFile, String bucketName) {
        // bucket 不存在,创建
        if (!bucketExists(bucketName)) {
            makeBucket(bucketName);
        }
        return putObject(multipartFile, bucketName, null);
    }

    /**
     * 文件上传
     *
     * @param multipartFile
     * @param bucketName
     * @return
     */
    public static String uploadObject(MultipartFile multipartFile, String bucketName, String region) {
        // bucket 不存在,创建
        if (!bucketExists(bucketName, region)) {
            makeBucket(bucketName, region);
        }
        return putObject(multipartFile, bucketName, region);
    }

    /**
     * 文件下载
     *
     * @param bucketName
     * @param region
     * @param fileName
     * @return
     */
    public static void downloadObject(String bucketName, String region, String fileName) {
        HttpServletResponse response = RequestHolder.getResponse();
        // 设置编码
        response.setCharacterEncoding(XmpWriter.UTF8);
        try (ServletOutputStream os = response.getOutputStream();
             GetObjectResponse is = minioClient.getObject(
                     GetObjectArgs.builder()
                             .bucket(bucketName)
                             .region(region)
                             .object(fileName)
                             .build());) {

            response.setHeader("Content-Disposition", "attachment;fileName=" +
                    new String(fileName.getBytes("gb2312"), "ISO8859-1"));
            ByteStreams.copy(is, os);
            os.flush();
        } catch (Exception e) {
            ResponseEnum.MIN_IO_FILE_DOWNLOAD_FAIL.assertFail(e);
        }
    }

    /**
     * 获取文件
     *
     * @param bucketName
     * @param region
     * @param fileName
     * @return
     */
    public static String getObjectUrl(String bucketName, String region, String fileName) {
        String objectUrl = null;
        try {
            objectUrl = minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .region(region)
                            .object(fileName)
                            .build());
        } catch (Exception e) {
            ResponseEnum.MIN_IO_FILE_GET_FAIL.assertFail(e);
        }
        return objectUrl;
    }

    /**
     * 删除文件
     *
     * @param bucketName
     * @param objectName
     */
    public static void deleteObject(String bucketName, String objectName) {
        try {
            minioClient.removeObject(
                    RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            ResponseEnum.MIN_IO_FILE_DELETE_FAIL.assertFail(e);
        }
    }

    /**
     * 删除文件
     *
     * @param bucketName
     * @param region
     * @param objectName
     */
    public static void deleteObject(String bucketName, String region, String objectName) {
        try {
            minioClient.removeObject(
                    RemoveObjectArgs.builder().bucket(bucketName).region(region).object(objectName).build());
        } catch (Exception e) {
            ResponseEnum.MIN_IO_FILE_DELETE_FAIL.assertFail(e);
        }
    }

    /**
     * 上传文件
     *
     * @param multipartFile
     * @param bucketName
     * @return
     */
    private static String putObject(MultipartFile multipartFile, String bucketName, String region) {
        try (InputStream inputStream = multipartFile.getInputStream()) {
            // 上传文件的名称
            String fileName = multipartFile.getOriginalFilename();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .region(region)
                    .object(fileName)
                    .stream(inputStream, multipartFile.getSize(), ObjectWriteArgs.MIN_MULTIPART_SIZE)
                    .contentType(multipartFile.getContentType())
                    .build());
            // 返回访问路径
            return getObjectUrl(bucketName, region, fileName);
        } catch (Exception e) {
            ResponseEnum.MIN_IO_FILE_UPLOAD_FAIL.assertFail(e);
        }
        return null;
    }

    /**
     * 上传文件
     *
     * @param bucketName
     * @param region
     * @param objectName
     * @param filePath
     */
    private static String putObject(String bucketName, String region, String objectName, String filePath) {
        try {
            minioClient.uploadObject(
                    UploadObjectArgs.builder()
                            .bucket(bucketName)
                            .region(region)
                            .object(objectName)
                            .filename(filePath)
                            .build());
            // 返回访问路径
            return getObjectUrl(bucketName, region, objectName);
        } catch (Exception e) {
            ResponseEnum.MIN_IO_FILE_UPLOAD_FAIL.assertFail(e);
        }
        return null;
    }
}

测试

controller控制器入口方法,上传完之后可以在管理后台查看到。

	/**
     * minio上传文件
     *
     */
    @PostMapping("/minio-upload")
    @ApiOperation(value="minio上传文件")
    public BaseResponse minioUpload(MultipartFile file){
        return BaseResponse.ok(MinIoUtil.uploadObject(file,"gourd","suzhou"));
    }
    /**
     * minio下载文件
     *
     */
    @GetMapping("/minio-download")
    @ApiOperation(value="minio下载文件")
    public void minioDownload(){
        MinIoUtil.downloadObject("gourd","suzhou","paixu.gif");
    }

在这里插入图片描述

结语

至此,MinIo整合实现文件上传、下载功能就好了。如有错误之处,欢迎指正。

代码摘自本人的开源项目cloud-plus:https://blog.csdn.net/HXNLYW/article/details/104635673

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现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/`路径下。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值