MinIO Java SDK设置子域名模式获取存储桶中对象的预签名链接

省流版:在你创建完客户端后,调用客户端的enableVirtualStyleEndpoint方法,示例代码如下。

      MinioClient minioClient =
          MinioClient.builder()
              .endpoint("http://dyfile.com")
              .credentials("*****", "******")
              .build();
      minioClient.enableVirtualStyleEndpoint();    // 这一步是关键!

以下是详细的探索、分析步骤。

近日,我们公司计划在公司自己的服务器上搭建一个对象存储服务,以便于我们有的时候给客户分享一些文件,在经过了一段时间的技术选型之后,我们选择了MiniIO这一开源对象存储服务,在下载、部署完成之后,我们便开始了测试。首先,我们的启动命令如下

sudo MINIO_ROOT_USER=xxxxx MINIO_ROOT_PASSWORD=xxxxxx MINIO_DOMAIN=dyfile.com ./minio server /mnt/data --console-address ":9001"

在这里,我们配置了MINIO_DOMAIN=dyfile.com ,这一参数可以在官方文档中查阅到,如下

Set to the Fully Qualified Domain Name (FQDN) MinIO accepts Bucket DNS (Virtual Host)-style requests on.

For example, setting MINIO_DOMAIN=minio.example.net directs MinIO to accept an incoming connection request to the data bucket at data.minio.example.net.

If this setting is omitted, the default is to only accept path-style requests. For example, minio.example.net/data.

设置为完全限定域名(FQDN),MinIO接受桶DNS(虚拟主机)风格的请求。

例如,设置MINIO_DOMAIN=minio.example.net指示MinIO接受对data.minio.example.net上的数据桶的传入连接请求。

如果省略此设置,默认是只接受路径风格的请求。例如,minio.example.net/data。

我新建了一个叫test的存储桶,并将其设置为了private(私有)模式,这样的话,直接通过桶域名访问是会被拒绝的,这样也保障了存储桶的安全。

那么,我们想要与我们的客户分享文件时,该怎么办呢?答案是:我们可以通过Java SDK来生成预签名链接,这个预签名链接可以设置一个有效期。

然后,我们参照MinIO给出的示例代码(如下)进行测试。(获取链接为https://github.com/minio/minio-java/blob/master/examples/GetPresignedObjectUrl.java


import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.errors.MinioException;
import io.minio.http.Method;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class GetPresignedObjectUrl {
  public static void main(String[] args)
      throws IOException, NoSuchAlgorithmException, InvalidKeyException {
    try {
      MinioClient minioClient =
          MinioClient.builder()
              .endpoint("http://test.dyfile.com")
              .credentials("*******", "********")
              .build();

      String url =
          minioClient.getPresignedObjectUrl(
              GetPresignedObjectUrlArgs.builder()
                  .method(Method.GET)
                  .bucket("test")
                  .object("IMG_20230724_0002.jpg")
                  .expiry(10)
                  .build());
      System.out.println(url);
    } catch (MinioException e) {
      System.out.println("Error occurred: " + e);
    }
  }
}

这样的话,会提示我找不到这个桶。这是为什么呢?经过调试,发现,这个会请求http://test.dyfile.com/test,相当于把存储桶的名字加了两遍,那当然是找不到了!

然后,我们试着将构建预签名链接请求的那里的bucket名字设置为空,却又报了错

Exception in thread "main" java.lang.IllegalArgumentException:  : bucket name must be at least 3 and no more than 63 characters long

参数校验没有通过!于是,我们又把这里的bucket名字加上,然后,又把创建client时的那个URL的test删掉了,即

      MinioClient minioClient =
          MinioClient.builder()
              .endpoint("http://dyfile.com")
              .credentials("*****", "*******")
              .build();

这下子倒是能生成链接了,但是,仔细一看http://dyfile.com/test/IMG_20230724_0002.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=admin%2F20231129%2Fcn-nmg%2Fs3%2Faws4_request&X-Amz-Date=20231129T022943Z&X-Amz-Expires=10&X-Amz-SignedHeaders=host&X-Amz-Signature=e06e96939ab8a839a83bc488280a4e9b54eab596aacbb17e51968e5db496e6f8

这不对啊,我想要的是子域名模式,这不又变成路径模式了吗?

在各种网站苦苦搜索,也在这个SDK的GitHub的issue(议题)区搜了搜,发现没有任何理想答案!

然后,一步步调试,发现,是在S3Base这个类中有个buildUrl方法,在这里,有如下代码

      if (enforcePathStyle || !useVirtualStyle) {    // 强制使用路径模式或者没有使用虚拟主机模式
        urlBuilder.host(host);
        urlBuilder.addEncodedPathSegment(S3Escaper.encode(bucketName));    // 将存储桶名字拼接在URL后面
      } else {
        urlBuilder.host(bucketName + "." + host);    // 否则,用存储桶名字+.+服务端host的形式
      }

再调试,发现,这个useVirtualStyle是这个S3Base类中的一个成员变量,再点进去查看一下,发现,可以在创建完客户端之后,调用客户端的enableVirtualStyleEndpoint方法,然后就可以是子域名模式(也就是虚拟主机模式)了!运行之后,果然如我们所愿。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员老于

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值