Ich versuche, mit Retrofit 2.0 einen HTTP-POST für den Server durchzuführen
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();
Der Server gibt einen Fehler zurück, der besagt, dass die Datei ungültig ist.
Das ist seltsam, weil ich versucht habe, dieselbe Datei mit demselben Format unter iOS (unter Verwendung einer anderen Bibliothek) hochzuladen, aber es wurde erfolgreich hochgeladen.
Ich frage mich, wie ich ein Bild mit Retrofit 2.0 richtig hochladen kann .
Sollte ich es vor dem Hochladen zuerst auf der Festplatte speichern?
PS: Ich habe die Nachrüstung für andere mehrteilige Anforderungen verwendet, die kein Bild enthalten, und sie wurden erfolgreich abgeschlossen. Das Problem ist, wenn ich versuche, ein Byte in den Körper aufzunehmen.
android
retrofit
androidhttpclient
retrofit2
JayVDiyk
quelle
quelle
Antworten:
Ich hebe die Lösung sowohl in 1.9 als auch in 2.0 hervor, da sie für einige nützlich ist
In
1.9
, ich denke , die bessere Lösung ist es, die Datei auf der Festplatte zu speichern und als typisierte Datei verwenden , wie:RetroFit 1.9
(Ich weiß nichts über Ihre serverseitige Implementierung) haben eine ähnliche API-Schnittstellenmethode
Und benutze es gerne
Für RetroFit 2 Verwenden Sie die folgende Methode
RetroFit 2.0 (Dies war eine Problemumgehung für ein Problem in RetroFit 2, das jetzt behoben ist. Die richtige Methode finden Sie in der Antwort von jimmy0251. )
API-Schnittstelle:
Verwenden Sie es wie:
quelle
@Multipart @POST("/api/Accounts/editaccount") Call<User> editUser(@PartMap Map<String, RequestBody> params);
und wenn Sie die Datei haben:Map<String, RequestBody> map = new HashMap<>(); RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpg"), file); map.put("file\"; filename=\"" + file.getName(), fileBody);
MultiPartBody.Part
Es gibt eine korrekte Möglichkeit, eine Datei mit ihrem Namen mit Retrofit 2 ohne Hack hochzuladen :
API-Schnittstelle definieren:
Datei wie folgt hochladen:
Dies zeigt nur das Hochladen von Dateien. Sie können in derselben Methode auch andere Parameter mit
@Part
Anmerkungen hinzufügen .quelle
MultipartBody.Part
Argumente in derselben API verwenden.@Part("images[]") List<MultipartBody.Part> images
aber es gibt Fehler, dass@Part parameters using the MultipartBody.Part must not include a part name
@Body MultipartBody multipartBody
undMultipartBody.Builder
zum Senden einer Sammlung von Bildern verwenden.Ich habe Retrofit 2.0 für meine Registrierungsbenutzer verwendet und ein mehrteiliges / Formular-Dateibild und einen Text vom Registrierungskonto gesendet
Verwenden Sie in meiner RegisterActivity eine AsyncTask
In meiner Register.java-Klasse wird Retrofit mit synchronem Aufruf verwendet
In der Schnittstelle von RegisterService
Für die Utilities analysieren Sie die InputStream-Antwort
quelle
Update-Code für das Hochladen von Bilddateien in Retrofit2.0
Wechseln Sie
MediaType.parse("image/*")
zuMediaType.parse("image/jpeg")
quelle
@Multipart
dann@Part
müssen Annotation einen Namen liefern oder MultipartBody.Part Parametertyp verwenden.@Part("profile_pic\"; filename=\"pp.png "
Hinzufügen zu der Antwort von @insomniac . Sie können ein erstellen
Map
, um den Parameter für dasRequestBody
Einschließen des Bildes festzulegen.Code für die Schnittstelle
Code für die Java-Klasse
quelle
Es ist also eine sehr einfache Möglichkeit, Ihre Aufgabe zu erfüllen. Sie müssen den folgenden Schritt ausführen: -
1. Erster Schritt
Sie müssen den gesamten Anruf als tätigen
@Multipart request
.item
undimage number
ist nur ein String-Körper, der eingewickelt istRequestBody
. Wir verwenden dasMultipartBody.Part class
, mit dem wir den tatsächlichen Dateinamen neben den Binärdateidaten mit der Anfrage senden können2. Zweiter Schritt
Jetzt haben Sie
image path
und Sie müssen infile
.Now konvertierenfile
inRequestBody
using-MethodeRequestBody.create(MediaType.parse("multipart/form-data"), file)
. Jetzt müssen Sie Ihre MethodeRequestBody requestFile
inMultipartBody.Part
using konvertierenMultipartBody.Part.createFormData("Image", file.getName(), requestBody);
.ImageNumber
undItemId
sind meine anderen Daten, die ich an den Server senden muss, damit ich auch beides macheRequestBody
.Für mehr Information
quelle
Das Hochladen von Dateien mit Retrofit ist ganz einfach. Sie müssen Ihre API-Oberfläche als erstellen
in dem obigen Code Bild ist der Schlüssel Name also , wenn Sie PHP verwenden Sie schreiben , werden $ _FILES [ ‚Bild‘] [ ‚tmp_name‘] , dies zu erhalten. Und filename = "myfile.jpg" ist der Name Ihrer Datei, die mit der Anfrage gesendet wird.
Um die Datei hochzuladen, benötigen Sie eine Methode, die Ihnen den absoluten Pfad vom Uri gibt.
Jetzt können Sie den folgenden Code verwenden, um Ihre Datei hochzuladen.
Weitere Informationen finden Sie in diesem Tutorial zum Nachrüsten von Dateien .
quelle
Kotlin-Version mit Update für den Entzug von
RequestBody.create
:Nachrüstschnittstelle
und zum Hochladen
Danke an @ jimmy0251
quelle
Verwenden Sie nicht mehrere Parameter im Funktionsnamen geht nur mit einfacher wenige args Konvention , die die Lesbarkeit von Codes erhöhen , denn dies kann man wie tun -
Es kann sein , mehrere Ausnahmen, die auftreten können , während mit Retrofit, die alle die Ausnahmen als Code dokumentiert , eine Komplettlösung zu
retrofit2/RequestFactory.java
. Sie können zwei Funktionen ausführenparseParameterAnnotation
undparseMethodAnnotation
wo Sie Ausnahmen auslösen können, gehen Sie dies bitte durch. Dies spart Ihnen viel Zeit als Googeln / Stackoverflowquelle
In Kotlin ist es ganz einfach, Erweiterungsmethoden von toMediaType , asRequestBody und toRequestBody zu verwenden. Hier ein Beispiel:
Hier poste ich ein paar normale Felder zusammen mit einer PDF-Datei und einer Bilddatei mit mehreren Teilen
Dies ist eine API-Deklaration mit Nachrüstung:
und so nennt man es eigentlich:
quelle