Estoy tratando de hacer una POST HTTP al servidor usando Retrofit 2.0
MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain");
MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/*");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG,90,byteArrayOutputStream);
profilePictureByte = byteArrayOutputStream.toByteArray();
Call<APIResults> call = ServiceAPI.updateProfile(
RequestBody.create(MEDIA_TYPE_TEXT, emailString),
RequestBody.create(MEDIA_TYPE_IMAGE, profilePictureByte));
call.enqueue();
El servidor devuelve un error diciendo que el archivo no es válido.
Esto es extraño porque he intentado cargar el mismo archivo con el mismo formato en iOS (usando otra biblioteca), pero se carga con éxito.
Me pregunto cuál es la forma correcta de cargar una imagen usando Retrofit 2.0 .
¿Debo guardarlo en el disco antes de cargarlo?
PD: He usado la actualización para otra solicitud de varias partes que no incluye imagen y se completaron con éxito. El problema es cuando intento incluir un byte en el cuerpo.
android
retrofit
androidhttpclient
retrofit2
JayVDiyk
fuente
fuente
Respuestas:
Estoy destacando la solución en 1.9 y 2.0 ya que es útil para algunos
En
1.9
, creo que la mejor solución es guardar el archivo en el disco y usarlo como archivo escrito como:RetroFit 1.9
(No sé acerca de su implementación del lado del servidor) tiene un método de interfaz API similar a este
Y úsalo como
Para RetroFit 2, use el siguiente método
RetroFit 2.0 (Esta fue una solución para un problema en RetroFit 2 que se solucionó ahora; para el método correcto, consulte la respuesta de jimmy0251 )
Interfaz API:
Úselo como:
fuente
@Multipart @POST("/api/Accounts/editaccount") Call<User> editUser(@PartMap Map<String, RequestBody> params);
Y cuando tenga el archivo:Map<String, RequestBody> map = new HashMap<>(); RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpg"), file); map.put("file\"; filename=\"" + file.getName(), fileBody);
MultiPartBody.Part
Hay una forma correcta de cargar un archivo con su nombre con Retrofit 2 , sin ningún hack :
Definir interfaz API:
Sube un archivo como este:
Esto demuestra solo la carga de archivos, también puede agregar otros parámetros en el mismo método con
@Part
anotaciones.fuente
MultipartBody.Part
argumentos en la misma API.@Part("images[]") List<MultipartBody.Part> images
pero da error que@Part parameters using the MultipartBody.Part must not include a part name
@Body MultipartBody multipartBody
yMultipartBody.Builder
para enviar una colección de imágenes.Utilicé Retrofit 2.0 para mis usuarios registrados, envié una imagen de archivo multipart / form y texto desde la cuenta de registro
En mi RegisterActivity, use una AsyncTask
Y en mi clase Register.java es donde usar Retrofit con llamada sincrónica
En la interfaz de RegisterService
Para el análisis de utilidades de la respuesta InputStream
fuente
Código de actualización para cargar archivos de imagen en Retrofit2.0
Cambiar
MediaType.parse("image/*")
aMediaType.parse("image/jpeg")
fuente
@Multipart
una@Part
anotación, debe proporcionar un nombre o usar el tipo de parámetro MultipartBody.Part.@Part("profile_pic\"; filename=\"pp.png "
Agregando a la respuesta dada por @insomniac . Puede crear un
Map
para poner el parámetro paraRequestBody
incluir la imagen.Código para la interfaz
Código para la clase Java
fuente
Entonces, es una forma muy simple de lograr su tarea. Debe seguir el siguiente paso: -
1. Primer paso
Necesita hacer toda la llamada como
@Multipart request
.item
yimage number
es solo un cuerpo de cuerda que está envueltoRequestBody
. Usamos elMultipartBody.Part class
que nos permite enviar el nombre real del archivo además de los datos del archivo binario con la solicitud2. Segundo paso
Ahora tiene
image path
y necesita convertir enfile
. Ahora conviertafile
enRequestBody
usar el métodoRequestBody.create(MediaType.parse("multipart/form-data"), file)
. Ahora lo que necesita para convertir suRequestBody requestFile
enMultipartBody.Part
el uso de métodoMultipartBody.Part.createFormData("Image", file.getName(), requestBody);
.ImageNumber
yItemId
es mi otra información que necesito enviar al servidor, así que también hago ambas cosas enRequestBody
.Para más información
fuente
Cargar archivos usando Retrofit es bastante simple. Necesita construir su interfaz api como
en la imagen de código anterior está el nombre de la clave, por lo que si está utilizando php, escribirá $ _FILES ['image'] ['tmp_name'] para obtener esto. Y filename = "myfile.jpg" es el nombre del archivo que se envía con la solicitud.
Ahora para cargar el archivo necesita un método que le dará la ruta absoluta desde el Uri.
Ahora puede usar el siguiente código para cargar su archivo.
Para obtener una explicación más detallada, puede visitar este Tutorial de actualización de archivos de carga .
fuente
Versión de Kotlin con actualización para depricación de
RequestBody.create
:Interfaz de actualización
y subir
Gracias a @ jimmy0251
fuente
No use múltiples parámetros en el nombre de la función, solo vaya con una simple convención de args que aumentará la legibilidad de los códigos , para esto puede hacer lo siguiente:
Puede haber múltiples excepciones que puede encontrar al usar Retrofit, todas las excepciones documentadas como código , tienen un tutorial
retrofit2/RequestFactory.java
. puede realizar dos funcionesparseParameterAnnotation
y,parseMethodAnnotation
si puede lanzar una excepción, continúe con esto, le ahorrará mucho tiempo que buscar en Google / stackoverflowfuente
en kotlin es bastante fácil, usando métodos de extensiones de toMediaType , asRequestBody y toRequestBody aquí hay un ejemplo:
aquí estoy publicando un par de campos normales junto con un archivo pdf y un archivo de imagen usando multiparte
Esta es la declaración de API que utiliza la modificación:
y aquí está cómo llamarlo realmente:
fuente