簡體   English   中英

在Android上使用Retrofit2將文件上傳到Amazon S3時出現問題

[英]Problems uploading file to Amazon S3 using Retrofit2 on Android

我試圖將文件(由設備的相機拍攝)上傳到Amazon S3。 不幸的是,請求失敗並帶有InvalidArgument異常:

<Code>InvalidArgument</Code><Message></Message><ArgumentName>x-amz-acl</ArgumentName>

該請求應采用以下形式:

------WebKitFormBoundaryPJf5u1BglONosgFh
Content-Disposition: form-data; name="key"

uploads/FooBar/<SOME ID>/db8218d9-2e45-4ed4-bd44-70019bbf6047_${filename}
------WebKitFormBoundaryPJf5u1BglONosgFh
Content-Disposition: form-data; name="success_action_status"

201
------WebKitFormBoundaryPJf5u1BglONosgFh
Content-Disposition: form-data; name="acl"

public-read
------WebKitFormBoundaryPJf5u1BglONosgFh
Content-Disposition: form-data; name="Expires"

Wed, 11 May 2016 13:26:28 GMT
------WebKitFormBoundaryPJf5u1BglONosgFh
Content-Disposition: form-data; name="file"; filename="blob"
Content-Type: image/png


------WebKitFormBoundaryPJf5u1BglONosgFh--

我啟用了Retrofit logger,但是不幸的是它沒有輸出請求正文。

我沒有在標題中設置x-amz-acl

我的服務如下:

 public interface FileUploadService {
      @Multipart
      @POST("/")
      Call<FileUpload> upload(@PartMap LinkedHashMap<String,String> params, @Part MultipartBody.Part file);
 }

在我的相機片段中,我這樣做:

// Get my image
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);

RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), bytes);
MultipartBody.Part body = MultipartBody.Part.createFormData("file","filename.jpg", requestFile);

// Get parameters from upload URL request
LinkedHashMap<String, String> params = response.body().getFields();


uploadService.upload(params, body).enqueue(new Callback<FileUpload>() {

         @Override
         public void onResponse(Call<FileUpload> call, Response<FileUpload> response) {
              // DO STUFF
         }

         @Override
         public void onFailure(Call<FileUpload> call, Throwable t) {
             // DO STUFF
         }
});

URL請求中的參數都是正確的。

如果您不介意解決問題的其他方法,請讓我建議以下方法。

  • Apache Commons網站下載commons-net-3.4.jar
  • 解壓縮下載的文件后,將jar文件添加到您的libs/文件夾中。
  • 然后右鍵單擊->添加為庫到您的應用程序模塊。 應該很簡單。 您會注意到它會將庫添加到build.gradle文件中並可以使用。
  • 准備就緒后,無論您要執行哪種方法來執行文件上傳的后台操作,都可以使用以下示例代碼:

     public class SyncFileToServer extends AsyncTask<String, Void, String>{ @Override protected String doInBackground(String... params){ FTPClient ftpClient = new FTPClient(); try{ ftpClient.connect("xxx.xxx.x.xxx"); ftpClient.login("username", "password"); ftpClient.setFileType(FTP.BINARY_FILE_TYPE); ftpClient.enterLocalPassiveMode(); File file = new File("path/to/file"); FileInputStream inputStream = new FileInputStream(file); if(ftpClient.storeFile("filetotransfer", inputStream)){ ftpClient.disconnect(); return "success"; }else{ ftpClient.disconnect(); return "ERROR"; } }catch (IOException e){ e.printStackTrace(); } } return null; } 

由於必須從設備中獲取文件位置,因此可以將其作為參數傳遞給異步任務甚至服務。 操作完成后,您可以使用事件或您喜歡的東西相應地更新UI。

我認為使用commons庫要容易得多,而且速度更快,因為您只需要編寫幾行代碼即可!

希望這可以幫助您解決問題並祝您好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM