Diese Frage wurde vielleicht schon einmal gestellt, aber nein, sie wurde nicht endgültig beantwortet. Wie genau postet man rohen ganzen JSON im Hauptteil einer Retrofit-Anfrage?
Siehe ähnliche Frage hier . Oder ist diese Antwort richtig, dass sie formularcodiert und als Feld übergeben werden muss ? Ich hoffe wirklich nicht, da die Dienste, mit denen ich mich verbinde, nur rohen JSON im Hauptteil des Beitrags erwarten. Sie sind nicht so eingerichtet, dass sie nach einem bestimmten Feld für die JSON-Daten suchen.
Ich möchte dies nur ein für alle Mal mit den Restperts klären . Eine Person antwortete, Retrofit nicht zu verwenden. Der andere war sich der Syntax nicht sicher. Ein anderer meint, ja, es kann getan werden, aber nur, wenn seine Form url-codiert und in einem Feld platziert ist (das ist in meinem Fall nicht akzeptabel). Nein, ich kann nicht alle Dienste für meinen Android-Client neu codieren. Und ja, es ist in großen Projekten sehr üblich, unformatiertes JSON zu veröffentlichen, anstatt JSON-Inhalte als Feldeigenschaftswerte zu übergeben. Lassen Sie es uns richtig machen und weitermachen. Kann jemand auf die Dokumentation oder das Beispiel verweisen, das zeigt, wie dies gemacht wird? Oder geben Sie einen gültigen Grund an, warum dies nicht möglich ist / sein sollte.
UPDATE: Eines kann ich mit 100% iger Sicherheit sagen. Sie können dies in Googles Volley tun. Es ist direkt eingebaut. Können wir dies in Retrofit tun?
RequestBody
so ->RequestBody body = RequestBody.create(MediaType.parse("text/plain"), text);
für detaillierte Antwort futurestud.io/tutorials/…Antworten:
Die
@Body
Anmerkung definiert einen einzelnen Anforderungshauptteil.Da Retrofit standardmäßig Gson verwendet, werden die
FooRequest
Instanzen als JSON als einziger Hauptteil der Anforderung serialisiert.Anrufen mit:
Ergibt den folgenden Körper:
In den Gson-Dokumenten erfahren Sie viel mehr über die Funktionsweise der Objektserialisierung.
Wenn Sie wirklich "rohen" JSON als Körper selbst senden möchten (aber verwenden Sie dazu bitte Gson!), Können Sie trotzdem Folgendes verwenden
TypedInput
:TypedInput ist definiert als "Binärdaten mit einem zugeordneten MIME-Typ". Es gibt zwei Möglichkeiten, Rohdaten mit der obigen Deklaration einfach zu senden:
Verwenden Sie TypedByteArray , um Rohbytes und den JSON- MIME-Typ zu senden:
Unterklasse TypedString zum Erstellen einer
TypedJsonString
Klasse:Verwenden Sie dann eine Instanz dieser Klasse ähnlich # 1.
quelle
TypedString
seit es entfernt wurde?RequestBody
einen Rohkörper erstellen.java.lang.IllegalArgumentException: Unable to create @Body converter for class MatchAPIRequestBody (parameter #1)
Anstelle von Klassen können wir beispielsweise auch direkt verwenden
HashMap<String, Object>
, um Körperparameter zu sendenquelle
IllegalArgumentException: Unable to create @Body converter for java.util.HashMap<java.lang.String, java.lang.Object>
mit Moshi. Ich denke, Gson wird benötigt, damit dies funktioniertJa, ich weiß, dass es spät ist, aber wahrscheinlich würde jemand davon profitieren.
Verwenden von Retrofit2:
Ich bin gestern Abend auf dieses Problem bei der Migration von Volley zu Retrofit2 gestoßen (und wie OP feststellt, wurde dies direkt in Volley integriert
JsonObjectRequest
), und obwohl Jakes Antwort die richtige für Retrofit1.9 ist , hat Retrofit2 keineTypedString
.In meinem Fall musste
Map<String,Object>
ein gesendet werden, das einige Nullwerte enthalten konnte, die in ein JSONObject konvertiert wurden (das nicht mitfliegt@FieldMap
, spezielle Zeichen auch nicht konvertiert werden, einige werden konvertiert). Befolgen Sie daher den @bnorms-Hinweis und wie von Square angegeben :Dies ist also eine Option mit
RequestBody
undResponseBody
:In Ihrer Schnittstelle verwenden
@Body
mitRequestBody
Erstellen
RequestBody
Sie in Ihrem Aufrufpunkt ein , geben Sie an, dass es sich um MediaType handelt, und konvertieren Sie Ihre Karte mit JSONObject in das richtige Format:Hoffe das hilft jemandem!
Eine elegante Kotlin-Version des oben genannten, mit der Sie die Parameter der JSON-Konvertierung im Rest Ihres Anwendungscodes abstrahieren können:
quelle
JsonObjectRequest
Sie dies nur tun. Gute Antwort.post a null value
eine Eigenschaft im requestBody zu finden, die ansonsten ignoriert wurde.jsonParams.put("code", some_code);
in der dritten Zeile?Wenn Sie in Retrofit2 Ihre Parameter in RAW senden möchten, müssen Sie Skalare verwenden .
füge dies zuerst in dein gradle ein:
Ihre Schnittstelle
Aktivität
quelle
GsonConverterFactory
,.toString()
ist das nicht notwendig. Sie können erklären ,Call<User> getUser(@Body JsonObject body);
indemJsonObject
stattJSONObject
der und übergebenparamObject
direkt. Es wird gut funktionieren.Verwenden
JsonObject
ist so wie es ist:Erstellen Sie Ihre Benutzeroberfläche folgendermaßen:
Erstellen Sie das JsonObject gemäß der jsons-Struktur.
Rufen Sie den Service an:
Und das ist es! Meiner persönlichen Meinung nach ist es viel besser, als Pojos zu machen und mit dem Klassenkampf zu arbeiten. Das ist viel sauberer.
quelle
Ich mag besonders Jakes Vorschlag für die obige
TypedString
Unterklasse . Sie können in der Tat eine Vielzahl von Unterklassen erstellen, die auf den Arten von POST-Daten basieren, die Sie hochfahren möchten, wobei jede ihre eigenen benutzerdefinierten konsistenten Optimierungen enthält.Sie haben auch die Möglichkeit, Ihren JSON POST-Methoden in Ihrer Retrofit-API eine Header-Annotation hinzuzufügen.
… Aber die Verwendung einer Unterklasse ist offensichtlicher selbstdokumentierend.
quelle
1) Abhängigkeiten hinzufügen-
2) Api Handler Klasse machen
3) Erstellen Sie Bean-Klassen aus Json Schema 2 Pojo
http://www.jsonschema2pojo.org/
4) Schnittstelle für API-Aufrufe erstellen
5) Machen Sie JsonObject für die Übergabe an body als Parameter
6) Rufen Sie Api so an
quelle
Ich habe festgestellt, dass ein zusammengesetztes Objekt, wenn Sie es als
@Body
Parameter verwenden, mit den Nachrüstungen nicht gut funktioniertGSONConverter
(unter der Annahme, dass Sie dies verwenden). Sie müssen verwendenJsonObject
und nicht,JSONObject
wenn Sie damit arbeiten, es fügt hinzu,NameValueParams
ohne ausführlich darüber zu sein - Sie können das nur sehen, wenn Sie eine weitere Abhängigkeit von Protokollierungs-Interceptor und anderen Spielereien hinzufügen.Was ich am besten gefunden habe, um dies anzugehen, ist die Verwendung
RequestBody
. Sie wenden Ihr ObjektRequestBody
mit einem einfachen API-Aufruf an und starten es. In meinem Fall konvertiere ich eine Karte:und das ist der Aufruf:
quelle
Fügen Sie ScalarsConverterFactory zur Nachrüstung hinzu:
in gradle:
Ihre Nachrüstung:
Ändern Sie den @ Body-Parameter Ihrer Aufrufschnittstelle in String. Vergessen Sie nicht, Folgendes hinzuzufügen
@Headers("Content-Type: application/json")
:jetzt kannst du raw json posten.
quelle
Sie können Hashmap verwenden, wenn Sie nicht für jeden API-Aufruf eine Pojo-Klasse erstellen möchten.
Und dann so senden
quelle
Nach so viel Mühe festgestellt, dass der grundlegende Unterschied darin besteht, dass Sie den Parameter
JsonObject
anstelle vonJSONObject
als senden müssen .quelle
Verwenden Sie Folgendes, um json zu senden
und an url weitergeben
quelle
Basierend auf der Top-Antwort habe ich eine Lösung, um nicht für jede Anfrage POJOs erstellen zu müssen.
Beispiel, ich möchte diesen JSON posten.
dann erstelle ich eine gemeinsame Klasse wie diese:
Endlich, wenn ich einen Json brauche
Die mit Annotation gekennzeichnete Anforderung
@Body
kann dann an Retrofit übergeben werden.quelle
Wenn Sie keine zusätzlichen Klassen erstellen oder verwenden möchten,
JSONObject
können Sie a verwendenHashMap
.Nachrüstschnittstelle:
Anruf:
quelle
Dinge, die erforderlich sind, um rohen JSON in Retrofit zu senden.
1) Stellen Sie sicher, dass Sie den folgenden Header hinzufügen und alle anderen doppelten Header entfernen. Da in den offiziellen Unterlagen von Retrofit ausdrücklich erwähnt wird:
2) a. Wenn Sie eine Konverterfactory verwenden, können Sie Ihren JSON als String, JSONObject, JsonObject und sogar als POJO übergeben. Habe auch geprüft, dass
ScalarConverterFactory
nicht nurGsonConverterFactory
der Job notwendig ist.2) b. Wenn Sie KEINE Konverterfabrik verwenden, MÜSSEN Sie den RequestBody von okhttp3 verwenden, wie in der Dokumentation von Retrofit angegeben:
3) Erfolg !!
quelle
Dies ist, was mich für die aktuelle Version von
retrofit
2.6.2 funktioniert ,Zunächst müssen wir der Liste unserer Gradle-Abhängigkeiten einen Skalarkonverter hinzufügen, der die Konvertierung von java.lang.String-Objekten in Text- / Nur-Anforderungskörper übernimmt.
Dann müssen wir eine Konverterfabrik an unseren Nachrüstbauer übergeben. Später wird Retrofit mitgeteilt, wie der an den Dienst übergebene @ Body-Parameter konvertiert werden soll.
Dann Nachrüstservice mit einem String-Body-Parameter.
Erstellen Sie dann den JSON-Body
Rufen Sie Ihren Service an
quelle
✅✅✅✅✅✅✅✅✅✅✅✅ Arbeitslösung ✅✅✅✅✅✅✅✅✅✅✅✅
Während der Erstellung
OkHttpClient
wird dies für die Nachrüstung verwendet.Fügen Sie einen Interceptor wie diesen hinzu.
Jetzt ist Ihre jeder Retrofit Aufruf der URL und Anforderungstext wird geloggt werden in
Logcat
. Filtern Sie es nach"gsonrequest"
quelle
Ich habe Folgendes versucht: Wenn Sie Ihre Retrofit-Instanz erstellen, fügen Sie diese Konverterfabrik dem Retrofit-Builder hinzu:
quelle
Ich habe mein Problem basierend auf der Antwort von TommySM gelöst (siehe oben). Aber ich musste mich nicht anmelden, ich habe Retrofit2 zum Testen der https GraphQL API wie folgt verwendet:
Definierte meine BaseResponse-Klasse mithilfe von JSON-Annotationen (import jackson.annotation.JsonProperty).
Definierte die Aufrufprozedur in der Schnittstelle:
Im Testkörper als apicall bezeichnet: Erstellen Sie eine Variable vom Typ MyRequest (z. B. "myLittleRequest").
quelle
Um die hier gegebenen Antworten klarer zu gestalten, können Sie auf diese Weise die Erweiterungsfunktionen verwenden. Dies ist nur möglich, wenn Sie Kotlin verwenden
Wenn Sie mit
com.squareup.okhttp3:okhttp:4.0.1
den älteren Methoden der Erzeugung von Objekten von Media und RequestBody sind veraltet und können nicht verwendet werden in Kotlin .Wenn Sie die Erweiterungsfunktionen verwenden möchten, um ein MediaType- Objekt und ein ResponseBody- Objekt aus Ihren Zeichenfolgen abzurufen, fügen Sie zunächst der Klasse, in der Sie sie verwenden möchten, die folgenden Zeilen hinzu.
Auf diese Weise können Sie jetzt direkt ein Objekt von MediaType abrufen
Um ein Objekt von RequestBody zu erhalten, konvertieren Sie zuerst das JSONObject, das Sie auf diese Weise an eine Zeichenfolge senden möchten. Sie müssen das mediaType-Objekt an dieses übergeben.
quelle
Ich wollte die Geschwindigkeit von Volley und Nachrüstung für das Senden und Empfangen von Daten vergleichen, die ich unter dem Code geschrieben habe (für den Nachrüstteil).
erste Abhängigkeit:
Dann Schnittstelle:
und eine Funktion zum Festlegen von Parametern zum Posten von Daten auf dem Server (In MainActivity):
Und ich fand Retrofit in meinem Fall schneller als Volley.
quelle