[Megrez Boot] starter-minio

本文介绍了一款基于SpringBoot的MinIO客户端程序配置及对象存储操作方法。提供了详细的属性配置指南,包括服务器参数、连接参数等,并展示了如何进行对象上传、下载、删除等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MinIO是一款开源的对象存储服务器。本项目基于Spring Boot自动配置MinioClient,开发MinIO客户端程序更方便。

项目源码:Gitee

简介

megrez.boot.autoconfigure.minio.MinioProperties属性配置

@Data
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {

    
    /** 服务器参数 */
    private Server server = new Server();
    /** 连接参数 */
    private Connection connection = new Connection();
    /** 连接参数 */
    private Proxy proxy = new Proxy();

    @Data
    public static class Proxy {
        private String host;
        private Integer port;
    }

    @Data
    public static class Connection {
        /**
         * Define the connect timeout for the Minio Client.
         */
        private Duration connectTimeout = Duration.ofSeconds(10);

        /**
         * Define the write timeout for the Minio Client.
         */
        private Duration writeTimeout = Duration.ofSeconds(60);

        /**
         * Define the read timeout for the Minio Client.
         */
        private Duration readTimeout = Duration.ofSeconds(10);
    }

    @Data
    public static class Server {

        /**
         * URL for Minio instance. Can include the HTTP scheme. Must include the port.
         * If the port is not provided, then the port of the HTTP is taken.
         */
        private String endpoint = "127.0.0.1";

        private Integer port = 9000;

        /**
         * Access key (login) on Minio instance
         */
        private String accessKey = "admin";

        /**
         * Secret key (password) on Minio instance
         */
        private String secretKey = "admin";

        /**
         * If the scheme is not provided in {@code url} property, define if the
         * connection is done via HTTP or HTTPS.
         */
        private boolean secure = false;
    }

}

megrez.boot.autoconfigure.minio.MinioAutoConfiguration自动配置

@Slf4j
@Configuration
@ConditionalOnClass(MinioClient.class)
@EnableConfigurationProperties(MinioProperties.class)
public class MinioAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MinioClient minioClient(MinioProperties properties, ObjectProvider<MinioConfigurer> configurers) {

        final Server server = properties.getServer();
        final Connection connection = properties.getConnection();
        final Proxy proxy = properties.getProxy();

        log.info("Initializing MinioClient [{}:{}]", server.getEndpoint(), server.getPort());

        final MinioClient.Builder builder = MinioClient.builder()
                .endpoint(server.getEndpoint(), server.getPort(), server.isSecure())
                .credentials(server.getAccessKey(), server.getSecretKey());

        if (StringUtils.hasText(proxy.getHost())) {
            log.info("Http proxy enabled [{}:{}]}", proxy.getHost(), proxy.getPort());
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .proxy(new java.net.Proxy(java.net.Proxy.Type.HTTP,
                            new InetSocketAddress(proxy.getHost(), proxy.getPort())))
                    .build();
            builder.httpClient(okHttpClient);
        }

        // 自定义配置处理
        configurers.forEach(configurer -> configurer.configure(builder));

        MinioClient minioClient = builder.build();
        minioClient.setTimeout(
                connection.getConnectTimeout().toMillis(),
                connection.getWriteTimeout().toMillis(),
                connection.getReadTimeout().toMillis());
        return minioClient;
    }

    @Bean
    @ConditionalOnMissingBean
    public MinioObjectClient minioObjectClient(MinioClient minioClient) {
        return new MinioObjectClient(minioClient);
    }

    @Bean
    @ConditionalOnMissingBean
    public MinioBucketClient minioBucketClient(MinioClient minioClient) {
        return new MinioBucketClient(minioClient);
    }
}

megrez.boot.autoconfigure.minio.MinioObjectClient对象操作服务


@RequiredArgsConstructor
public class MinioObjectClient {
    private final MinioClient client;

    /**
     * 上传对象流
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param stream     流
     * @param consumer   builder消费
     * @return
     */
    public ObjectWriteResponse putObject(String bucketName, String objectName, InputStream stream,
            Consumer<PutObjectArgs.Builder> consumer) {
        try {
            PutObjectArgs.Builder builder = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(stream, stream.available(), -1);

            if (consumer != null) {
                consumer.accept(builder);
            }

            return client.putObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 上传对象流
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param stream     流
     * @return
     */
    public ObjectWriteResponse putObject(String bucketName, String objectName, InputStream stream) {
        return putObject(bucketName, objectName, stream, null);
    }

    /**
     * 获取对象流
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     * @return
     */
    public GetObjectResponse getObject(String bucketName, String objectName, Consumer<GetObjectArgs.Builder> consumer) {
        try {
            GetObjectArgs.Builder builder = GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);

            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.getObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 获取对象流
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public GetObjectResponse getObject(String bucketName, String objectName) {
        return getObject(bucketName, objectName, null);
    }

    /**
     * 获取对象流-支持端点续传
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param offset     起始字节的位置
     * @param length     要读取的长度 (可选,如果无值则代表读到对象结尾)
     * @return
     */
    public GetObjectResponse getObject(String bucketName, String objectName, Long offset, Long length) {
        return getObject(bucketName, objectName, builder -> {
            builder.offset(offset);
            if (length != null) {
                builder.length(length);
            }
        });
    }

    /**
     * 获取对象信息和对象的元数据
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     * @return
     */
    public StatObjectResponse statObject(String bucketName, String objectName,
            Consumer<StatObjectArgs.Builder> consumer) {
        try {
            StatObjectArgs.Builder builder = StatObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);

            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.statObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 获取对象信息和对象的元数据
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public StatObjectResponse statObject(String bucketName, String objectName) {
        return statObject(bucketName, objectName, null);
    }

    /**
     * 对象是否存在
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public boolean existObject(String bucketName, String objectName) {
        try {
            StatObjectResponse response = statObject(bucketName, objectName, null);
            return response != null;
        } catch (MinioRuntimeException e) {
            return false;
        }
    }

    /**
     * 获取对象的元数据
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public Map<String, String> getObjectUserMetadata(String bucketName, String objectName) {
        return statObject(bucketName, objectName).userMetadata();
    }

    /**
     * 获取预签名对象网址, 默认Method.GET方法,分享链接地址失效时间为7天
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   bilder消费
     * @return
     */
    public String getPresignedObjectUrl(String bucketName, String objectName,
            Consumer<GetPresignedObjectUrlArgs.Builder> consumer) {
        try {
            GetPresignedObjectUrlArgs.Builder builder = GetPresignedObjectUrlArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .method(Method.GET);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.getPresignedObjectUrl(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param method     方法, GET, HEAD, POST, PUT, DELETE;
     * @param expiry     失效时间(以秒为单位),默认是7天,不得大于七天
     * @return
     */
    public String getPresignedObjectUrl(String bucketName, String objectName, Method method, Duration expiry) {
        return getPresignedObjectUrl(bucketName, objectName, builder -> {
            builder.method(method);
            if (expiry != null) {
                builder.expiry((int) expiry.toSeconds());
            }
        });
    }

    /**
     * 根据对象前缀查询对象
     * 
     * @param bucketName 桶
     * @param consumer   builder消费
     * @return
     */
    public List<Item> listObjects(String bucketName, Consumer<ListObjectsArgs.Builder> consumer) {
        try {
            ListObjectsArgs.Builder builder = ListObjectsArgs.builder()
                    .bucket(bucketName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            Iterable<Result<Item>> iterable = client.listObjects(builder.build());
            return StreamSupport
                    .stream(iterable.spliterator(), true)
                    .map(itemResult -> {
                        try {
                            return itemResult.get();
                        } catch (InvalidKeyException | ErrorResponseException | IllegalArgumentException
                                | InsufficientDataException | InternalException | InvalidResponseException
                                | NoSuchAlgorithmException | ServerException | XmlParserException | IOException e) {
                            throw new MinioRuntimeException(e);
                        }
                    })
                    .collect(Collectors.toList());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * 根据对象前缀查询对象
     * 
     * @param bucketName 桶
     * @param prefix     桶中对象的前缀 默认 空字符串
     * @param recursive  是否递归子目录
     * @return
     */
    public List<Item> listObjects(String bucketName, String prefix, Boolean recursive) {
        return listObjects(bucketName, builder -> {
            if (StringUtils.hasText(prefix)) {
                builder.prefix(prefix);
            }
            if (recursive != null) {
                builder.recursive(recursive);
            }
        });
    }

    /**
     * 组合源对象列表, 通过使用服务器端副本组合来自不同源对象的数据来创建对象,服务器上已存在的对象列表再次组合成一个对象
     * 
     * @param bucketName       桶
     * @param objectName       对象
     * @param sourceObjectList 组合组合的源对象列表
     * @param consumer         builder消费
     * @return
     */
    public ObjectWriteResponse composeObject(String bucketName, String objectName, List<ComposeSource> sourceObjectList,
            Consumer<ComposeObjectArgs.Builder> consumer) {
        try {
            ComposeObjectArgs.Builder builder = ComposeObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .sources(sourceObjectList);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.composeObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * 组合源对象列表, 通过使用服务器端副本组合来自不同源对象的数据来创建对象,服务器上已存在的对象列表再次组合成一个对象
     * 
     * @param bucketName       桶
     * @param objectName       对象
     * @param sourceObjectList 组合组合的源对象列表
     * @return
     */
    public ObjectWriteResponse composeObject(String bucketName, String objectName,
            List<ComposeSource> sourceObjectList) {
        return composeObject(bucketName, objectName, sourceObjectList, null);
    }

    /**
     * 复制对象
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param source     源对象
     * @param consumer   builder消费
     * @return
     */
    public ObjectWriteResponse copyObject(String bucketName, String objectName, CopySource source,
            Consumer<CopyObjectArgs.Builder> consumer) {
        try {
            CopyObjectArgs.Builder builder = CopyObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .source(source);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.copyObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * 复制对象
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param source     源对象
     * @return
     */
    public ObjectWriteResponse copyObject(String bucketName, String objectName, CopySource source) {
        return copyObject(bucketName, objectName, source, null);
    }

    /**
     * 设置对象的标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param tags       标签
     * @param consumer   builder消费
     */
    public void setObjectTags(String bucketName, String objectName, Tags tags,
            Consumer<SetObjectTagsArgs.Builder> consumer) {
        try {
            SetObjectTagsArgs.Builder builder = SetObjectTagsArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .tags(tags);
            if (consumer != null) {
                consumer.accept(builder);
            }
            client.setObjectTags(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 设置对象的标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param tags       标签
     */
    public void setObjectTags(String bucketName, String objectName, Tags tags) {
        setObjectTags(bucketName, objectName, tags, null);
    }

    /**
     * 获取对象的标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     * @return
     */
    public Tags getObjectTags(String bucketName, String objectName, Consumer<GetObjectTagsArgs.Builder> consumer) {
        try {
            GetObjectTagsArgs.Builder builder = GetObjectTagsArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.getObjectTags(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 获取对象的标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @return
     */
    public Tags getObjectTags(String bucketName, String objectName) {
        return getObjectTags(bucketName, objectName, null);
    }

    /**
     * 删除对象标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     */
    public void deleteObjectTags(String bucketName, String objectName,
            Consumer<DeleteObjectTagsArgs.Builder> consumer) {
        try {
            DeleteObjectTagsArgs.Builder builder = DeleteObjectTagsArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            client.deleteObjectTags(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 删除对象标签
     * 
     * @param bucketName 桶
     * @param objectName 对象
     */
    public void deleteObjectTags(String bucketName, String objectName) {
        deleteObjectTags(bucketName, objectName, null);
    }

    /**
     * 删除单个对象
     * 
     * @param bucketName 桶
     * @param objectName 对象
     * @param consumer   builder消费
     */
    public void deleteObject(String bucketName, String objectName, Consumer<RemoveObjectArgs.Builder> consumer) {
        try {
            RemoveObjectArgs.Builder builder = RemoveObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            client.removeObject(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 
     * 删除单个对象
     * 
     * @param bucketName 桶
     * @param objectName 对象
     */
    public void deleteObject(String bucketName, String objectName) {
        deleteObject(bucketName, objectName, null);
    }

    /**
     * 删除多个对象
     * 
     * @param bucketName  桶
     * @param objectNames 对象列表
     * @param consumer    builder消费
     */
    public List<DeleteError> deleteObjects(String bucketName, List<DeleteObject> objectNames,
            Consumer<RemoveObjectsArgs.Builder> consumer) {
        try {
            RemoveObjectsArgs.Builder builder = RemoveObjectsArgs.builder()
                    .bucket(bucketName)
                    .objects(objectNames);
            if (consumer != null) {
                consumer.accept(builder);
            }
            Iterable<Result<DeleteError>> iterable = client.removeObjects(builder.build());
            return StreamSupport.stream(iterable.spliterator(), true).map(result -> {
                try {
                    return result.get();
                } catch (InvalidKeyException | ErrorResponseException | IllegalArgumentException
                        | InsufficientDataException | InternalException | InvalidResponseException
                        | NoSuchAlgorithmException | ServerException | XmlParserException | IOException e) {
                    throw new MinioRuntimeException(e);
                }
            }).collect(Collectors.toList());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 删除多个对象
     * 
     * @param bucketName  桶
     * @param objectNames 对象列表
     * @return
     */
    public List<DeleteError> deleteObjects(String bucketName, List<DeleteObject> objectNames) {
        return deleteObjects(bucketName, objectNames, null);
    }
}

megrez.boot.autoconfigure.minio.MinioBucketClient桶操作服务

@RequiredArgsConstructor
public class MinioBucketClient {
    private final MinioClient client;

    /**
     * 桶是否存在
     * 
     * @param bucketName 桶名
     * @param consumer   builder消费
     * @return
     */
    public boolean bucketExists(String bucketName, Consumer<BucketExistsArgs.Builder> consumer) {
        try {
            BucketExistsArgs.Builder builder = BucketExistsArgs.builder()
                    .bucket(bucketName);

            if (consumer != null) {
                consumer.accept(builder);
            }

            return client.bucketExists(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 桶是否存在
     * 
     * @param bucketName 桶名
     * @return
     */
    public boolean bucketExists(String bucketName) {
        return bucketExists(bucketName, null);
    }

    /**
     * 所有桶信息
     * 
     * @return
     */
    public List<Bucket> listBuckets() {
        try {
            return client.listBuckets();
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }

    }

    /**
     * 创建桶 
     * 
     * @param bucketName 桶名
     * @param consumer builder消费
     */
    public void makeBucket(String bucketName, Consumer<MakeBucketArgs.Builder> consumer) {
        try {
            MakeBucketArgs.Builder builder = MakeBucketArgs.builder()
                    .bucket(bucketName);

            if (consumer != null) {
                consumer.accept(builder);
            }

            client.makeBucket(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }

    }

    /**
     * 创建桶 
     * 
     * @param bucketName 桶名
     */
    public void makeBucket(String bucketName) {
        makeBucket(bucketName, null);
    }


    /**
     * 获取存储桶中的对象锁定配置
     * 
     * @param bucketName 桶名
     * @param consumer   builder消费
     * @return
     */
    public ObjectLockConfiguration getObjectLockConfiguration(String bucketName,
            Consumer<GetObjectLockConfigurationArgs.Builder> consumer) {
        try {
            GetObjectLockConfigurationArgs.Builder builder = GetObjectLockConfigurationArgs.builder()
                    .bucket(bucketName);
            if (consumer != null) {
                consumer.accept(builder);
            }
            return client.getObjectLockConfiguration(builder.build());
        } catch (Exception e) {
            throw new MinioRuntimeException(e);
        }
    }

    /**
     * 获取存储桶中的对象锁定配置
     * 
     * @param bucketName 桶名
     * @return
     */
    public ObjectLockConfiguration getObjectLockConfiguration(String bucketName) {
        return getObjectLockConfiguration(bucketName, null);
    }
}

完整实现参考源代码

还有更多的项目参考,megrez-oss是对象存储服务,基于本地文件系统的存储,或基于MinIO的存储服务

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值