当前位置: 首页 > 面试题库 >

使用Retrofit2将文件上传到AWS S3预签名URL

王长卿
2023-03-14
问题内容

我正在尝试使用预签名的URL将文件上传到Amazon的S3。我从生成URL的服务器获取URL,并将其作为JSON对象的一部分发送给我。我将URL作为字符串获取,如下所示:

https://com-example-mysite.s3-us-
east-1.amazonaws.com/userFolder/ImageName?X-Amz-Security-
Token=xxfooxx%2F%2F%2F%2F%2F%2F%2F%2F% 2F%2F%2Fxxbarxx%3D&X-Amz-Algorithm =
xxAlgoxx&X-Amz-Date = 20170831T090152Z&X-Amz-SignedHeaders = host&X-Amz-
Expires = 3600&X-Amz-Credential = xxcredxx&X-Amz-Signature

不幸的是,当我将其传递给Retrofit2时,它会修改String并尝试将其制成URL。我已经设置好encoding=true了,可以解决大多数问题,但不能完全解决。我知道字符串按原样工作。我在邮递员中尝试过并获得成功的回应。

1st我尝试仅将String(除了我作为baseUrl剪切的东西)整体放入Path

public interface UpdateImageInterface {
    @PUT("{url}")
    Call<Void> updateImage(@Path(value="url", encoded=true) String url, Body RequestBody image);
}

调用代码:

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://com-example-mysite.s3-us-east-1.amazonaws.com/userFolder/")
            .build();

    UpdateImageInterface imageInterface = retrofit.create(UpdateImageInterface.class);
    // imageUrl is "ImageName..."
    Call<Void> call = imageInterface.updateImage(imageUrl, requestFile);

除“?”外,此方法大部分有效 (在“ ImageName”之后)转换为“%3F”。这会导致请求错误/ 400。

我的下一个尝试是使用Retrofit2创建查询,然后将整个String(包含多个查询)转储到查询中。

public interface UpdateImageInterface {
    @PUT("ImageName")
    Call<Void> updateProfilePhoto(@Query(value="X-Amz-Security-Token", encoded = true) String token, @Body RequestBody image);
}

调用代码:

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://com-example-mysite.s3-us-east-1.amazonaws.com/userFolder/")
            .build();

    UpdateImageInterface imageInterface = retrofit.create(UpdateImageInterface.class);
    // imageUrl is "xxfooxx..."
    Call<Void> call = imageInterface.updateImage(imageUrl, requestFile);

这得到“?” 正确呈现,但所有的“&”都更改为“%26”

最后,我尝试将整个String传入,baseUrl()但是由于结尾没有’/’而给出了IllegalArgumentException。

我知道我可以解析预签名的URL来进行多个查询,并在Retrofit2中将它们组合起来,因为应该完成查询,但我想避免这种处理。

要重申这个问题:

有没有一种方法可以使用Retrofit2轻松地(无需进行大量的字符串html" target="_blank">分析)将带有预签名URL的文件上传到S3?


问题答案:

在同事的帮助下,这就是解决方案。

public interface UpdateImageInterface {
    @PUT
    Call<Void> updateImage(@Url String url, @Body RequestBody image);
}

调用代码:

    String CONTENT_IMAGE = "image/jpeg";

    File file = new File(localPhotoPath);    // create new file on device
    RequestBody requestFile = RequestBody.create(MediaType.parse(CONTENT_IMAGE), file);

    /* since the pre-signed URL from S3 contains a host, this dummy URL will
     * be replaced completely by the pre-signed URL.  (I'm using baseURl(String) here
     * but see baseUrl(okhttp3.HttpUrl) in Javadoc for how base URLs are handled
     */
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://www.dummy.com/")
        .build();

    UpdateImageInterface imageInterface = retrofit.create(UpdateImageInterface.class);
    // imageUrl is the String as received from AWS S3
    Call<Void> call = imageInterface.updateImage(imageUrl, requestFile);

Javadoc,获取有关@Url(类网址)和
baseUrl()(类Retrofit.Builder)的信息

MediaType是OkHttp库中的一个类,通常与Retrofit(均来自Square)一起使用。可以在Javadoc中找到有关传递给parse方法的常量的信息。



 类似资料:
  • 我正在尝试使用预先签名的URL将文件上传到Amazon的S3。我从生成URL的服务器获取URL https://com-example-mysite.s3-us-east-1.amazonaws.com/userFolder/ImageName?X-Amz安全令牌=xxfoox///xxbarxx= 不幸的是,当我将其传递给Refught2时,它会修改试图将其转换为URL的字符串。我设置了,它解决

  • 我上传一个文件到AmazonS3有问题。我开发了一个Grails RESTful服务,它使用AWS Java SDK生成预签名URL。当客户端上传一个文件时,它首先检索一个预签名的URL,然后使用这个将文件直接上传到我的S3 bucket。所以我有一个Grails服务,它创建了一个预签名的URL,如下所示...

  • 这里是我的node.js预签名URL的生成 那么我在URL生成或卷曲方面的问题在哪里呢?谢谢

  • 我试图使用angular客户端将文件上传到Amazon S3。我已经使用NodeJs应用服务器生成了一个预先签名的URL。在将文件上传到预先签名的URL时,我收到一个错误,如下所示: "对预检请求的响应没有通过权限改造检查:请求的资源上没有'Access-Control-Allow-Origin'标头。因此不允许访问Origin'http://localhost:4200'。" 我已将以下 COR

  • 我正在开发一个特性,使用Angular/预签名url和API Gateway/lambda生成预签名url将文件上传到S3。 我的工作流描述如下: 从模板中获取选定文件 请求我的api(网关/lambda)使用文件名生成预签名的URL。 const body={filename:this.selectedfile.name}const preSignedUrl=await this.http.po