2016-06-03 2 views
0

내 코드 기반을 Retrofit 1.9에서 버전 2.0으로 업그레이드하려고합니다. 버전 1.9에서 이미지 업로드에 문제가 없습니다. 그러나 버전 2.0으로 변경 한 후에 S3 응답 오류가 발생합니다. 동적 URL을 인코딩하지 않으려면 Retrofit2에 요청하는 방법?

는 개조 V1.9에 이미지를 업로드 내 인터페이스 :

public interface IFileUploadAPI 
{ 
    @PUT("/{url}") 
    void uploadFile(@Path(value = "url", encode = false) String url, @Body() TypedFile file, 
        Callback<UploadFileResponse> callback); 
} 

나는 개조 2.0에서 코드를 다음으로 변경했습니다 :

public interface IFileUploadAPI 
{ 
    @PUT 
    Call<UploadFileResponse> uploadFile(@Url String url, @Body RequestBody file); 
} 

그리고 구현하고 있습니다 그것은 이런 식으로.

public class MyFileUploadAPI 
{ 
    private IFileUploadAPI mService; 

    public MyFileUploadAPI() 
    { 
     final Retrofit adapter = new Retrofit.Builder() // 
         .baseUrl(MyAPIConstant.API_URL_BASE) // This URL will be ignored as we are using dynamic url. So no matters what it is. 
         .addConverterFactory(GsonConverterFactory.create(GsonUtils.getGson())) // 
         .client(ASDKApplication.getInstance().getOkHttpClient()) // 
         .build(); 

     this.mService = adapter.create(IFileUploadAPI.class); 
    } 

    public void uploadFile(final String url, final String filePath, final String mimeType) 
    { 
     RequestBody file = RequestBody.create(MediaType.parse(mimeType), filePath); 
     Call<UploadFileResponse> call = mService.uploadFile(url, file); 
       call.enqueue(new Callback<HitchUploadFileResponse>() 
     { 
      @Override 
      public void onResponse(Call<UploadFileResponse> call, Response<UploadFileResponse> response) 
      { 
       UploadFileResponse uploadFileResponse = new UploadFileResponse(); 

       if (response.isSuccessful() && response.body() != null) 
       { 
        uploadFileResponse = response.body(); 
       } 

       // Rest of code... 
      } 

      @Override 
      public void onFailure(Call<UploadFileResponse> call, Throwable t) 
      { 
       Logger.error(TAG, "uploadFile.onFailure(), msg: " + t.getMessage()); 
      } 
     } 
    } 
} 

따라서, 사용자 클릭 Upload 버튼을, 나는 API를 호출하고 내게 전화를해야 URL을 반환 할 때. URL (금지 HTTP 상태 코드 403) 위의 전화

[{"uploadSignedURL":"https://my-account.s3.amazonaws.com/license/1000_front_1464988248.jpeg?AWSAccessKeyId=MY_ID\u0026Expires=1464991848\u0026Signature=NhStdEX8RH3J0uzvVa6h%2FvN6FZQ%3D","filePath":"license/1000_front_1464988248.jpeg","target":"driving_license_front_img"}] 

그리고 마지막으로 응답 : 응답은 좋아 보이는

<?xml version="1.0" encoding="UTF-8"?> 
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>MY_ID</AWSAccessKeyId><StringToSign>PUT 

image/jpeg; charset=utf-8 
1464991848 
/my-account/license/1000_front_1464988248.jpeg</StringToSign><SignatureProvided>NhStdEX8RH3J0uzvVa6h/vN6FZQ=</SignatureProvided><StringToSignBytes>50 55 54 0a 0a 69 6d 61 67 65 2f 6a 70 65 67 3b 20 63 68 61 72 73 65 74 3d 75 74 66 2d 38 0b 31 34 36 34 39 39 31 38 34 38 0a 2f 6d 79 74 65 6b 73 69 3a 67 72 61 62 68 69 45 63 68 2f 6c 69 63 65 6e 73 65 2f 31 30 30 30 5f 66 72 6f 6e 74 5f 31 34 36 34 39 38 38 32 34 38 2e 6a 70 65 67</StringToSignBytes><RequestId>2D6D08FE4E34FCE5</RequestId><HostId>tpvmJdeRxtAzPxOk2zFwMF2Ne6hmNMkcaM9D7m/I13iynYGJyqtC0U72B2t41SDYfPBjCRTVyOY=</HostId></Error> 

그래서, 어떤 생각을 감상 할 수있다. 감사.

답변

0

좋아, 나는 틀린 것을 발견했다.

okhttp은 을 내 contentType에 추가합니다. 따라서 contentTypecontentType: image/jpeg; charset=utf-8처럼됩니다. 나는 우편 배달부에서 테스트를했고 ; charset=utf-8의 삭제로 내 이미지를 업로드 할 수 있습니다.

https://stackoverflow.com/a/25560731/513413에는 charset을 추가하는 이유가 나와 있습니다. 그것은 내 이미지 파일에 경로를 전달하기 때문입니다. 하나 개 더 중요한 것은이

RequestBody file = RequestBody.create(MediaType.parse(mimeType), filePath);

RequestBody file = RequestBody.create(MediaType.parse(mimeType), new File(filePath));

에 쉽게 변경할 수 있습니다. S3에 이미지를 업로드하면 아마존은 빈 상태의 HTTP 상태 코드 200을 반환합니다. 따라서 인터페이스를 변경해야합니다.

public interface IFileUploadAPI 
{ 
    @PUT 
    Call<Void> uploadFile(@Url String url, @Body RequestBody file); 
} 
관련 문제