【问题标题】:Amazon S3 upload file and get URLAmazon S3 上传文件并获取 URL
【发布时间】:2012-06-14 02:02:10
【问题描述】:

是否可以通过单个操作将 txt/pdf/png 文件上传到 Amazon S3,并获取上传的文件 URL 作为响应?

如果是这样,AWS Java SDK 是否是我需要在我的 java struts2 Web 应用程序中添加的正确库?

请给我一个解决方案。

【问题讨论】:

标签: java amazon-s3 amazon-web-services


【解决方案1】:

不,你不能在一个动作中获得 URL,但两个 :)

首先,您可能必须在上传之前将文件公开,因为获取任何人都无法访问的 URL 是没有意义的。您可以按照 Michael Astreiko 的建议设置 ACL。 您可以通过调用getResourceUrlgetUrl 来获取资源URL。

AmazonS3Client s3Client = (AmazonS3Client)AmazonS3ClientBuilder.defaultClient();
s3Client.putObject(new PutObjectRequest("your-bucket", "some-path/some-key.jpg", new File("somePath/someKey.jpg")).withCannedAcl(CannedAccessControlList.PublicRead))
s3Client.getResourceUrl("your-bucket", "some-path/some-key.jpg");

注意1: getResourceUrlgetUrl 的区别在于getResourceUrl 在发生异常时会返回null。

注意2: getUrl 方法未在 AmazonS3 接口中定义。如果您使用标准构建器,则必须将对象强制转换为 AmazonS3Client。

【讨论】:

  • 值得注意的是,这只会导致对 AWS 的一次调用。如果您深入研究 Java SDK,您会发现 s3Client.getResourceUrl("your-bucket", "some-path/some-key.jpg") 无需调用 AWS 即可计算出 URL。
  • 这确实应该是推荐的答案。对于文件名包含空格的情况,另一个答案失败。在这种情况下,S3 上显示的文件名和 URL 后缀互不相同。上面的 s3Client.getUrl 方法正确处理了这个场景
  • 注意,getResourceUrl 不在最新的sdk中。
  • for latest sdk s3Client.getUrl("your-bucket", "some-path/some-key.jpg").toString(); 将获得公共 url。
  • 对于更新的 SDK 版本,请尝试s3Client.utilities().getUrl(getUrlRequest);
【解决方案2】:

您可以根据上传请求中指定的存储桶和文件名自行解决。

例如如果您的存储桶是mybucket 并且您的文件名为myfilename

https://mybucket.s3.amazonaws.com/myfilename

s3 位将根据您的存储桶所在的区域而有所不同。例如,我使用东南亚区域,因此我的网址如下:

https://mybucket.s3-ap-southeast-1.amazonaws.com/myfilename

【讨论】:

【解决方案3】:

@hussachai 和@Jeffrey Kemp 的答案非常好。但它们的共同点是返回的 url 是虚拟主机样式的,而不是路径样式的。有关 s3 url 样式的更多信息,可以参考AWS S3 URL Styles。如果有些人想要生成路径样式 s3 url。这是步骤。基本上一切都与@hussachai 和@Jeffrey Kemp 的答案相同,只有一行设置更改如下:

AmazonS3Client s3Client = (AmazonS3Client) AmazonS3ClientBuilder.standard()
                    .withRegion("us-west-2")
                    .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
                    .withPathStyleAccessEnabled(true)
                    .build();

// Upload a file as a new object with ContentType and title specified.
PutObjectRequest request = new PutObjectRequest(bucketName, stringObjKeyName, fileToUpload);
s3Client.putObject(request);
URL s3Url = s3Client.getUrl(bucketName, stringObjKeyName);
logger.info("S3 url is " + s3Url.toExternalForm());

这将生成如下网址: https://s3.us-west-2.amazonaws.com/mybucket/myfilename

【讨论】:

    【解决方案4】:

    对于 AWS 开发工具包 2+

    String key = "filePath";
    String bucketName = "bucketName";
    PutObjectResponse response = s3Client
                .putObject(PutObjectRequest.builder().bucket(bucketName ).key(key).build(), RequestBody.fromFile(file));
     GetUrlRequest request = GetUrlRequest.builder().bucket(bucketName ).key(key).build();
     String url = s3Client.utilities().getUrl(request).toExternalForm();
    

    【讨论】:

      【解决方案5】:

      同样,如果您想通过 s3Client 进行链接,您可以在下面使用。

      System.out.println("filelink: " + s3Client.getUrl("your_bucket_name", "your_file_key"));
      

      【讨论】:

        【解决方案6】:

        有点老了,但对于将来遇到这个问题的人来说仍然如此:

        假设您已经编写了 CredentialProvider 和 AmazonS3Client,您只需一行即可完成。

        看起来像这样:

         String ImageURL = String.valueOf(s3.getUrl(
                                          ConstantsAWS3.BUCKET_NAME, //The S3 Bucket To Upload To
                                          file.getName())); //The key for the uploaded object
        

        如果您没有编写 CredentialProvider 和 AmazonS3Client,那么只需在获取 URL 之前添加它们:

          CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
                getApplicationContext(),
                "POOL_ID", // Identity pool ID
                Regions.US_EAST_1 // Region
        );
        

        【讨论】:

          【解决方案7】:

          以下方法将文件上传到存储桶中的特定文件夹中,并返回生成的上传文件的url。

          private String uploadFileToS3Bucket(final String bucketName, final File file) {
              final String uniqueFileName = uploadFolder + "/" + file.getName();
              LOGGER.info("Uploading file with name= " + uniqueFileName);
              final PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, uniqueFileName, file);
              amazonS3.putObject(putObjectRequest);
              return ((AmazonS3Client) amazonS3).getResourceUrl(bucketName, uniqueFileName);
          }
          

          【讨论】:

            【解决方案8】:
            System.out.println("Link : " + s3Object.getObjectContent().getHttpRequest().getURI());
            

            使用此代码,您可以检索已上传文件到 S3 存储桶的链接。

            【讨论】:

              【解决方案9】:

              如果您使用的是 AWS-SDK,则返回的 data 对象包含 data.Location 中的对象 URL

              const AWS = require('aws-sdk')
              const s3 = new AWS.S3(config)
              
              s3.upload(params).promise()
                  .then((data)=>{
                      console.log(data.Location)
                  })
                  .catch(err=>console.log(err))

              【讨论】:

                【解决方案10】:

                要在上传之前公开文件,您可以使用PutObjectRequest#withCannedAcl 方法:

                myAmazonS3Client.putObject(new PutObjectRequest('some-grails-bucket',  'somePath/someKey.jpg', new    File('/Users/ben/Desktop/photo.jpg')).withCannedAcl(CannedAccessControlList.PublicRead))
                
                String url = myAmazonS3Client.getUrl('some-grails-bucket',  'somePath/someKey.jpg').toString();
                

                【讨论】:

                • 如何从这个请求中获取链接?
                • 这里并没有告诉我们如何获取上传资源的公共url。
                猜你喜欢
                • 2014-02-03
                • 2015-05-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-09-28
                • 1970-01-01
                相关资源
                最近更新 更多