2017-09-01 30 views
0

事前に署名されたURLを使用してAmazonのS3にファイルをアップロードしようとしています。 URLを生成するサーバーからURLを取得します。&はJSONオブジェクトの一部として私に送信します。私は文字列としてURLを取得し、このような何か:私はRetrofit2にこれを渡すときレトロフィット2を使用してAWS S3事前署名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%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=xxsignxx

は残念ながら、それはURLにそれを作るしようとする文字列を変更します。私はencoding=trueを設定しましたが、これは問題のほとんどを処理しましたが、完全ではありませんでした。私は文字列がそのまま動作することを知っています。私はPostman &でそれを試してみました。

私はちょうどパス

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

に全体として(私はbaseUrlにとして切り出さ何のため除く)、呼び出し元のコードの文字列を入れてみました第1回:これは除いて、ほとんど機能し

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

'?'正しくレンダリングされたが、「&」の全てが「%2​​6」に変更します

は、最後に私が baseUrl()で、全体の文字列を渡してみましたが、それは最後に「/」がないため、IllegalArgumentExceptionを与えます。

事前に署名されたURLを解析して複数のクエリを作成することができます。&は、Retrofit2でクエリを実行する必要があるため、それらを組み立てますが、その処理は避けてください。

簡単に(重い文字列の構文解析なし)Retrofit2を使用して事前に署名したURLでS3にファイルをアップロードする方法はあります:

は、質問を言い換えるするには?

+0

ライブラリやそれが依存するものは、少し壊れているようです。以下のコメントをご覧ください:https://github.com/square/retrofit/issues/1199 ...特に最後のものに注意してください。 –

+0

@ Michael-sqlbotはい、同じ問題のように思えます。私は解決策を見つけました。私は2,3日後に時間があるときに投稿します。 – Gary99

答えて

1

同僚の助けを借りて、これが解決策です。

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

電話番号:

/* 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)上の情報のため

Javadoc & baseUrl()(クラスRetrofit.Builder)

0

使用presigned URLを使ってS3に直接アップロード中に、次の。

@Multipart 
@PUT 
@Headers("x-amz-acl:public-read") 
Call<Void> uploadFile(@Url String url, @Header("Content-Type") String contentType, @Part MultipartBody.Part part); 
関連する問題