事前に署名されたURLを使用してAmazonのS3にファイルをアップロードしようとしています。URLを生成するサーバーからURLを取得し、JSONオブジェクトの一部として送信します。URLを文字列として取得します。次のようになります。
残念ながら、これをRetrofit2に渡すと、文字列が変更されてURLになります。私はencoding=true
問題の大部分を処理したが完全ではないものを設定しました。Stringがそのまま機能することはわかっています。私はPostmanでそれを試し、成功した応答を得ました。
最初に、文字列(baseUrlとして切り取ったものを除く)全体をパスに入れてみました
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を使用してクエリを作成しましたが、文字列全体(複数のクエリを含む)をクエリにダンプしました。
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」に変更されます
最後に、文字列全体を渡そうとしましたが、最後にbaseUrl()
「/」がないためにIllegalArgumentExceptionが発生します。
事前に署名されたURLを解析して複数のクエリを作成し、クエリを実行する必要があるため、Retrofit2でそれらをアセンブルできることは知っていますが、その処理は避けたいと思います。
質問を言い換えると:
Retrofit2を使用して、事前に署名された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);
@Url
(クラスUrl)およびbaseUrl()
(クラスRetrofit.Builder)に関する情報のJavadoc
MediaType
は、Retrofit(両方ともSquareから)でよく使用されるOkHttpライブラリのクラスです。parseメソッドに渡される定数に関する情報は、Javadocにあります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加