thread for example asynctask android download upload retrofit

android - for - retrofit post



Retrofit 2 archivo abajo/subir (5)

Estoy usando la versión 2.0.0-beta2 y tuve un problema al cargar la imagen al usar la solicitud de varias partes. Lo resolví utilizando esta respuesta: https://stackoverflow.com/a/32796626/2915075

La clave para mí fue utilizar POST estándar con MultipartRequestBody en lugar de la solicitud anotada de @Multipart.

Aquí está mi código:

Clase de servicio de actualización

@POST("photo") Call<JsonElement> uploadPhoto(@Body RequestBody imageFile, @Query("sessionId"));

Uso de la actividad, fragmento:

RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"), imageFile); MultipartBuilder multipartBuilder = new MultipartBuilder(); multipartBuilder.addFormDataPart("photo", imageFile.getName(), fileBody); RequestBody fileRequestBody = multipartBuilder.build(); //call mRestClient.getRetrofitService().uploadProfilePhoto(fileRequestBody, sessionId);

Estoy intentando descargar / bajar un archivo con la actualización 2, pero no puedo encontrar ejemplos de tutoriales sobre cómo hacerlo. Mi código para descargar es:

@GET("documents/checkout") public Call<File> checkout(@Query(value = "documentUrl") String documentUrl, @Query(value = "accessToken") String accessToken, @Query(value = "readOnly") boolean readOnly);

y

Call<File> call = RetrofitSingleton.getInstance(serverAddress) .checkout(document.getContentUrl(), apiToken, readOnly[i]); call.enqueue(new Callback<File>() { @Override public void onResponse(Response<File> response, Retrofit retrofit) { String fileName = document.getFileName(); try { System.out.println(response.body()); long fileLength = response.body().length(); InputStream input = new FileInputStream(response.body()); File path = Environment.getExternalStorageDirectory(); File file = new File(path, fileName); BufferedOutputStream output = new BufferedOutputStream( new FileOutputStream(file)); byte data[] = new byte[1024]; long total = 0; int count; while ((count = input.read(data)) != -1) { total += count; output.write(data, 0, count); } output.flush(); output.close(); } catch (IOException e) { String logTag = "TEMPTAG"; Log.e(logTag, "Error while writing file!"); Log.e(logTag, e.toString()); } } @Override public void onFailure(Throwable t) { // TODO: Error handling System.out.println(t.toString()); } });

He intentado con Call and Call pero nada parece funcionar.

El código del lado del servidor escribe los bytes del archivo en el flujo de salida de HttpServletResponse después de configurar correctamente los encabezados y el tipo mime.

¿Qué estoy haciendo mal?

Finalmente, el código de carga:

@Multipart @POST("documents/checkin") public Call<String> checkin(@Query(value = "documentId") String documentId, @Query(value = "name") String fileName, @Query(value = "accessToken") String accessToken, @Part("file") RequestBody file);

y

RequestBody requestBody = RequestBody.create(MediaType.parse(document.getMimeType()), file); Call<String> call = RetrofitSingleton.getInstance(serverAddress).checkin(documentId, document.getFileName(), apiToken, requestBody); call.enqueue(new Callback<String>() { @Override public void onResponse(Response<String> response, Retrofit retrofit) { System.out.println(response.body()); } @Override public void onFailure(Throwable t) { System.out.println(t.toString()); } });

¡Gracias!

Editar:

Después de la respuesta, la descarga solo produce un archivo dañado (sin @Streaming), la carga no lo hace también. Cuando uso el código anterior, el servidor devuelve un error 400. Después de cambiarlo a

RequestBody requestBody = RequestBody.create(MediaType.parse(document.getMimeType()), file); MultipartBuilder multipartBuilder = new MultipartBuilder(); multipartBuilder.addFormDataPart("file", document.getFileName(), requestBody); Call<String> call = RetrofitSingleton.getInstance(serverAddress).checkin(documentId, document.getFileName(), apiToken, multipartBuilder.build());

, la solicitud se ejecuta pero el servidor no parece recibir un archivo.

Código de fondo:

@RequestMapping(value = "/documents/checkin", method = RequestMethod.POST) public void checkInDocument(@RequestParam String documentId, @RequestParam String name, @RequestParam MultipartFile file, @RequestParam String accessToken, HttpServletResponse response)

¿Qué estoy haciendo mal? Pude usar el backend de Java simple con el HttpClient de Apache:

MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); builder.addBinaryBody("file", new File("E://temp//test.jpg")); HttpEntity httpEntity = builder.build(); System.out.println("HttpEntity " + EntityUtils.toString(httpEntity.)); HttpPost httpPost = new HttpPost(uri); httpPost.setEntity(httpEntity);

Editar v2

Para cualquier persona interesada, tanto el trabajo de actualización como el de descarga ahora son las siguientes soluciones:

Servicio:

@GET("documents/checkout") public Call<ResponseBody> checkout(@Query(value = "documentUrl") String documentUrl, @Query(value = "accessToken") String accessToken, @Query(value = "readOnly") boolean readOnly); @Multipart @POST("documents/checkin") public Call<String> checkin(@Query(value = "documentId") String documentId, @Query(value = "name") String fileName, @Query(value = "accessToken") String accessToken, @Part("file") RequestBody file);

Código de descarga:

Call<ResponseBody> call = RetrofitSingleton.getInstance(serverAddress) .checkout(document.getContentUrl(), apiToken, readOnly[i]); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Response<ResponseBody> response, Retrofit retrofit) { String fileName = document.getFileName(); try { File path = Environment.getExternalStorageDirectory(); File file = new File(path, fileName); FileOutputStream fileOutputStream = new FileOutputStream(file); IOUtils.write(response.body().bytes(), fileOutputStream); } catch (IOException e) { Log.e(logTag, "Error while writing file!"); Log.e(logTag, e.toString()); } } @Override public void onFailure(Throwable t) { // TODO: Error handling System.out.println(t.toString()); } });

Código de carga:

Call<String> call = RetrofitSingleton .getInstance(serverAddress).checkin(documentId, document.getFileName(), apiToken, multipartBuilder.build()); call.enqueue(new Callback<String>() { @Override public void onResponse(Response<String> response, Retrofit retrofit) { // Handle response here } @Override public void onFailure(Throwable t) { // TODO: Error handling System.out.println("Error"); System.out.println(t.toString()); } });


Para la descarga, puede utilizar ResponseBody como su tipo de devolución:

@GET("documents/checkout") @Streaming public Call<ResponseBody> checkout(@Query("documentUrl") String documentUrl, @Query("accessToken") String accessToken, @Query("readOnly") boolean readOnly);

y puede obtener el flujo de entrada ResponseBody en su llamada de vuelta -

Call<ResponseBody> call = RetrofitSingleton.getInstance(serverAddress) .checkout(document.getContentUrl(), apiToken, readOnly[i]); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Response<ResponseBody> response, Retrofit retrofit) { String fileName = document.getFileName(); try { InputStream input = response.body().byteStream(); // rest of your code

Su carga se ve bien a primera vista si su servidor maneja correctamente los mensajes de varias partes. ¿Está funcionando? Si no, ¿puedes explicar el modo de falla? También puedes simplificarlo si no lo haces en varias partes. Elimine la anotación @Multipart y convierta @Path a @Body -

@POST("documents/checkin") public Call<String> checkin(@Query("documentId") String documentId, @Query("name") String fileName, @Query("accessToken") String accessToken, @Body RequestBody file);


Puede consultar el tutorial para la descarga de imágenes usando Retrofit 2.0

Por el momento puede consultar las siguientes funciones para descargar imágenes:

void getRetrofitImage() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(url) .addConverterFactory(GsonConverterFactory.create()) .build(); RetrofitImageAPI service = retrofit.create(RetrofitImageAPI.class); Call<ResponseBody> call = service.getImageDetails(); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Response<ResponseBody> response, Retrofit retrofit) { try { Log.d("onResponse", "Response came from server"); boolean FileDownloaded = DownloadImage(response.body()); Log.d("onResponse", "Image is downloaded and saved ? " + FileDownloaded); } catch (Exception e) { Log.d("onResponse", "There is an error"); e.printStackTrace(); } } @Override public void onFailure(Throwable t) { Log.d("onFailure", t.toString()); } }); }

A continuación se muestra la descarga de la imagen de la parte de manejo de archivos con Retrofit 2.0

private boolean DownloadImage(ResponseBody body) { try { Log.d("DownloadImage", "Reading and writing file"); InputStream in = null; FileOutputStream out = null; try { in = body.byteStream(); out = new FileOutputStream(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg"); int c; while ((c = in.read()) != -1) { out.write(c); } } catch (IOException e) { Log.d("DownloadImage",e.toString()); return false; } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } int width, height; ImageView image = (ImageView) findViewById(R.id.imageViewId); Bitmap bMap = BitmapFactory.decodeFile(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg"); width = 2*bMap.getWidth(); height = 6*bMap.getHeight(); Bitmap bMap2 = Bitmap.createScaledBitmap(bMap, width, height, false); image.setImageBitmap(bMap2); return true; } catch (IOException e) { Log.d("DownloadImage",e.toString()); return false; } }

Espero que te ayude. Todo lo mejor. Feliz codificación :)


También tuve este problema. Así es como trato de resolver mi problema (RETROFIT 2)

//1. What We Need From Server ( upload.php Script ) public class FromServer { String result; } //2. Which Interface To Communicate Our upload.php Script? public interface ServerAPI { @Multipart @POST("upload.php")//Our Destination PHP Script Call<List<FromServer>> upload( @Part("file_name") String file_name, @Part("file") RequestBody description); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://192.168.43.135/retro/") // REMEMBER TO END with / .addConverterFactory(GsonConverterFactory.create()) .build(); } //3. How To Upload private void upload(){ ServerAPI api = ServerAPI.retrofit.create(ServerAPI.class); File from_phone = FileUtils.getFile(Environment.getExternalStorageDirectory()+"/aa.jpg"); //org.apache.commons.io.FileUtils RequestBody to_server = RequestBody.create(MediaType.parse("multipart/form-data"), from_phone); api.upload(from_phone.getName(),to_server).enqueue(new Callback<List<FromServer>>() { @Override public void onResponse(Call<List<FromServer>> call, Response<List<FromServer>> response) { Toast.makeText(MainActivity.this, response.body().get(0).result, Toast.LENGTH_SHORT).show(); } @Override public void onFailure(Call<List<FromServer>> call, Throwable t) { } }); } //4. upload.php <?php $pic = $_POST[''file_name'']; $pic = str_replace("/"", "", $pic); //REMOVE " from file name if(file_exists($pic)){unlink($pic);} $f = fopen($pic, "w"); fwrite($f,$_POST[''file'']); fclose($f); $arr[] = array("result"=>"Done"); print(json_encode($arr)); ?>