2015-04-18 15 views
6

Sto tentando di convertire tutti i miei asynctasks e il codice HttpPost per utilizzare Retrofit, fin qui tutto bene, ma ho problemi a caricare file utente su un bucket amazon s3. Il caricamento di file ha due parti:Caricamento multiparte su Amazon S3 utilizzando Retrofit

  1. api query per ottenere un UPLOAD_URL e Amazon params di upload.
  2. Carica file nella posizione specificata con parametri forniti in prima chiamata.

Ecco un esempio di elenco di parametri forniti dalla prima chiamata. Secondo la documentazione, questi valori possono essere modificati o non essere inclusi e la seconda chiamata api deve chiamare utilizzare questi parametri nell'ordine esatto in cui sono stati forniti.

"AWSAccessKeyId": "some_id",  
"key": "https://stackoverflow.com/users/1234/files/profile_pic.jpg", 
"acl": "private", 
"Filename": "profile_pic.jpg", 
"Policy": "some_opaque_string", 
"Signature": "another_opaque_string", 
"Content-Type": "image/jpeg" 

Per gestire il contenuto dinamico. Ho creato un convertitore personalizzato per avere il retrofit restituirmi una LinkedHashMap nella mia prima chiamata API.

public class CustomConverter implements Converter { 

@Override public Object fromBody(TypedInput typedInput, Type type) throws ConversionException {  
     ... 
     Type mapType = new TypeToken<LinkedHashMap<String, String>>(){}.getType(); 
     return new Gson().fromJson(JSON_STRING, mapType);  
} 

Poi, nella seconda chiamata API, Una volta ho questi valori sono creare un FormUrlEncodedTypedOutput iterando HashMap e aggiungendo ogni elemento.

FormUrlEncodedTypedOutput params = new FormUrlEncodedTypedOutput(); 
for (Map.Entry<String, String> entry : uploadParams.entrySet()) { 
      params.addField(KEY, VALUE); 
} 

Tutto sembra funzionare. Sto ricevendo i parametri necessari per il caricamento e l'ordine sembra essere coerente. Sono un po 'meno sicuro di come ho il mio setup di postmontaggio di retrofit multipart. Lo uso poi all'interno di una chiamata di retrofit sincrono all'interno di un intentservice.

@Multipart 
    @POST("/") 
    Response uploadFile(@Part ("whatdoesthisdo?") FormUrlEncodedTypedOutput params, @Part("File") TypedFile file); 

Questo genera un errore Amazon.

"code" : "InvalidArgument" 
"message" : "Bucket POST must contain a field named 'key'. If it is specified, please check the order of the fields." 

Sono stato su Google e sembra che Amazon preferisca il valore "chiave" per essere il primo? Tuttavia, se metto la "chiave" davanti a "AWSAccessKeyId" ottengo un errore 403 non autorizzato. Ho configurato correttamente la mia chiamata di aggiornamento? Se qualcuno potesse aiutarmi a capirlo, lo apprezzerei. Ci sono voluti alcuni giorni per convertire la maggior parte del mio codice di upload in retrofit e se sono stato bloccato su questo per un po '.

Grazie!

+0

Potete mostrare tutto il codice, se possibile, cercare di capire come per afferrare le informazioni rispedito dalla risposta della firma di Amazon S3 – Lion789

risposta

4

La soluzione era utilizzare @PartMap invece di FormUrlEncodedTypedOutput.

@Multipart 
@POST("/") 
Response uploadFile(@PartMap LinkedHashMap<String,String> params, @Part("File") TypedFile file); 
+0

Ehi hai qualche idea di come posso fare per ottenere la richiesta firmata da retrofit? Questa è la mia domanda su SO con il mio tentativo http://stackoverflow.com/questions/30411672/how-to-add-nodejs-s3-heroku-direct-upload-to-android – Lion789

Problemi correlati