使用Retrofit2将文件上传到AWS S3预签名URL [英] Upload a file to AWS S3 pre-signed URL using Retrofit2

查看:190
本文介绍了使用Retrofit2将文件上传到AWS S3预签名URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to upload a file to Amazon's S3 using a pre-signed URL. I get the URL from a server which generates the URL & sends it to me as part of a JSON object. I get the URL as a String, something like this:

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

Unfortunately, when I pass this to Retrofit2, it modifies the String attempting to make it into a URL. I've set encoding=true which took care of most of the problem but not completely. I know the String works as it is. I've tried it in Postman & get a successful response.

首先,我尝试将整个字符串(除了我作为baseUrl剪切掉的字符串外)整体放入路径

1st I tried just putting the String (except for what I cut out as baseUrl) as a whole into the 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.

This works mostly except the the '?' (after "ImageName") get converted to "%3F". This causes a Bad Request / 400.

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

My next attempt was to create a query with Retrofit2 but then dump the whole String (with multiple queries) into the query.

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"

This gets the '?' rendered correctly but all of the '&' get changed to "%26"

最后,我尝试在baseUrl()中传递整个String,但是由于结尾处没有'/'而给出了IllegalArgumentException.

Lastly I tried passing the whole String in baseUrl() but that gives an IllegalArgumentException for not having '/' on the end.

我知道我可以解析预签名的URL来进行多个查询&在应进行查询的情况下,将它们组装在Retrofit2中,但我想避免这种处理.

I know that I could parse the pre-signed URL to make multiple queries & assemble them in Retrofit2 as queries should be done but I'd like to avoid that processing.

要重述该问题:

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

Is there a way to easily (without heavy String parsing) upload a file to S3 with a pre-signed URL using Retrofit2?

推荐答案

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

With help from a colleague, this is the solution.

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类)

Javadoc for info on @Url (class Url) & baseUrl() (class Retrofit.Builder)

MediaType OkHttp 库中的类,通常与Retrofit(两者都来自正方形).可以在Javadoc中找到有关传递给parse方法的常量的信息.

MediaType is a class in the OkHttp library that is often used with Retrofit (both from Square). Info about constants passed to the parse method can be found in the Javadoc.

这篇关于使用Retrofit2将文件上传到AWS S3预签名URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆