Je souhaite télécharger un fichier binaire sur le serveur sous Android. Je teste la méthode Api par facteur:
Et c'est OK, comme vous le voyez, il existe une autre option que vous pouvez télécharger des fichiers en tant que données de formulaire (clé, valeur):
Tous les tutoriels (comme celui-ci ) décrivent comment télécharger des fichiers en tant que multipart/form-data
:
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("picture", file.getName(), requestFile);
Je recherche beaucoup mais je n'ai pas trouvé de moyen de télécharger un fichier binaire avec retrofit2.
Il n'y a qu'un seul problème dans le dépôt de mise à niveau qui demande Comment puis-je POST une image binaire en retrofit 2.0 beta?. J'utilise sa solution:
Service API:
@POST("trip/{tripId}/media/photos")
Call<MediaPost> postEventPhoto(
@Path("eventId") int tripId,
@Header("Authorization") String accessToken,
@Query("direction") String direction,
@Body RequestBody photo);
Votre interlocuteur:
InputStream in = new FileInputStream(new File(media.getPath()));
byte[] buf;
buf = new byte[in.available()];
while (in.read(buf) != -1);
RequestBody requestBody = RequestBody
.create(MediaType.parse("application/octet-stream"), buf);
Call<MediaPost> mediaPostCall = tripApiService.postTripPhoto(
tripId,
((GlobalInfo) getApplicationContext()).getApiAccessToken(),
direction,
requestBody);
Mais j'ai eu cette erreur:
Java.lang.IllegalArgumentException: @Body parameters cannot be used with form or multi-part encoding.
Qu'est ce qui ne va pas avec mon code? que devrais-je faire?
Après des heures de recherche, j'ai trouvé qu'il y avait un @Multipart
l'annotation reste dans l'interface API de mon code du dernier exemple! ce qui empêche d'envoyer des données binaires au serveur et la solution dans le référentiel de mise à niveau était OK!
J'ajoute juste une autre solution, car j'ai dû creuser un peu pour comprendre ce qui s'est passé dans la question en premier lieu.
Ma solution est d'obtenir le fichier binaire sous la forme d'un byte[]
directement, puis placez-le dans le RequestBody
. Donc à la fin, le code ressemblerait à ceci:
interface RetrofitService {
@POST("api/v1/upload_file")
Call<Void> uploadBinaryFile(@Body RequestBody body);
}
Et pour l'appeler:
public void uploadBinaryFile(File fileToUpload) {
retrofitService
.uploadBinaryFile(RequestBody.create(MediaType.parse("application/octet"),
Files.readAllBytes(fileToUpload));
}
C'est fondamentalement la même que la question originale de OP, mais juste pour des raisons de clarté, je laisserai cette réponse également au prochain lecteur.
J'ai eu le même problème, je voulais télécharger un fichier binaire (image). L'API était de Wordpress
J'ai suivi le code de la solution qui est donné à la fin de ce problème
Voici mon petit code modifié
@POST("wp-json/wp/v2/media/")
Call<ImagePostResult> postEventPhoto(
@Header("Authorization") String accessToken,
@Header("Content-Type") String contentType,
@Header("Content-Disposition") String contentDisposition,
@Body RequestBody photo);
Voici la demande
// For BasicAuth
String authHeader = getAuthHeader();
String contentType = "application/binary";
String contentDisposition = "attachment; filename = " + fileName;
RequestBody requestBodyee = null;
try {
InputStream in = new FileInputStream(file);
byte[] buf;
buf = new byte[in.available()];
while (in.read(buf) != -1) ;
requestBodyee = RequestBody
.create(MediaType.parse("application/octet-stream"), buf);
} catch (IOException e) {
e.printStackTrace();
}
Call<ImagePostResult> imagePostResultCall = apiInterface.postEventPhoto(
authHeader,
contentType,
contentDisposition,
requestBodyee);
imagePostResultCall.enqueue(new Callback<ImagePostResult>() {
@Override
public void onResponse(Call<ImagePostResult> call, Response<ImagePostResult> response) {
// Response Success
if (response.isSuccessful()) {
// yaay
}
}
@Override
public void onFailure(Call<ImagePostResult> call, Throwable t) {
Log.d(TAG, "onFailure: " + t);
}
});
juste MediaType == Null mon code:
private fun put(uploadUrl : String , localPath : String) {
val file = File(localPath)
val byteArray = file2Byte(localPath)!!
val responseBody = RequestBody.create(null , byteArray)
val call = HttpFactory.providerUp.up(uploadUrl , responseBody)
call.enqueue(object : Callback<ResponseBody> {
override fun onFailure(call : retrofit2.Call<ResponseBody>? , t : Throwable?) {
LogUtil.toast("Failure")
}
override fun onResponse(call : retrofit2.Call<ResponseBody>? , response : retrofit.Response<ResponseBody>?) {
if (response!!.code() == 200) {
LogUtil.toast("YES")
} else {
LogUtil.toast("NO")
}
}
})
}
@PUT
fun up2(@Url url : String ,@Body requestBody : RequestBody ) : Call<ResponseBody>
Vous pouvez également envoyer l'image en
//Api Interface
@Part MultipartBody.Part body
//Call in activity
file = FileUtils.getFile(this, uri);
reqFile = RequestBody.create(MediaType.parse("image/*"), file);
body = MultipartBody.Part.createFormData("uploaded_file", "Img_" + "_" + rightNow.getTimeInMillis() + ".jpg", reqFile);