使用Retrofit2将文件上传到AWS S3预签名URL [英] Upload a file to AWS S3 pre-signed URL using Retrofit2
问题描述
我正在尝试使用预先签名的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:
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屋!