Cette question a peut-être été posée auparavant mais non, elle n'a pas été résolue de manière définitive. Comment poster exactement un JSON entier brut dans le corps d'une demande de modification?
Voir la question similaire ici . Ou cette réponse est-elle correcte, elle doit être codée sous forme d'URL et passée sous forme de champ ? J'espère vraiment que non, car les services auxquels je me connecte n'attendent que du JSON brut dans le corps du message. Ils ne sont pas configurés pour rechercher un champ particulier pour les données JSON.
Je veux juste clarifier cela avec les experts une fois pour toutes. Une personne a répondu de ne pas utiliser Retrofit. L'autre n'était pas certain de la syntaxe. Un autre pense que oui, cela peut être fait mais seulement si sa forme est encodée en URL et placée dans un champ (ce n'est pas acceptable dans mon cas). Non, je ne peux pas recoder tous les services pour mon client Android. Et oui, il est très courant dans les grands projets de publier du JSON brut au lieu de passer sur le contenu JSON en tant que valeurs de propriété de champ. Faisons les choses correctement et continuons. Quelqu'un peut-il pointer la documentation ou l'exemple qui montre comment cela est fait? Ou donnez une raison valable pour laquelle cela ne peut / ne doit pas être fait.
MISE À JOUR: Une chose que je peux dire avec 100% de certitude. Vous POUVEZ le faire dans Google's Volley. Il est intégré. Pouvons-nous faire cela dans Retrofit?
RequestBody
comme ça ->RequestBody body = RequestBody.create(MediaType.parse("text/plain"), text);
pour une réponse détaillée futurestud.io/tutorials/…Réponses:
L'
@Body
annotation définit un seul corps de demande.Étant donné que Retrofit utilise Gson par défaut, les
FooRequest
instances seront sérialisées en JSON comme seul corps de la demande.Appeler avec:
Donnera le corps suivant:
Les documents Gson ont beaucoup plus sur le fonctionnement de la sérialisation d'objets.
Maintenant, si vous voulez vraiment envoyer JSON "brut" comme corps vous-même (mais veuillez utiliser Gson pour cela!), Vous pouvez toujours utiliser
TypedInput
:TypedInput est défini comme "Données binaires avec un type MIME associé". Il y a deux façons d'envoyer facilement des données brutes avec la déclaration ci-dessus:
Utilisez TypedByteArray pour envoyer des octets bruts et le type MIME JSON:
Sous-classe TypedString pour créer une
TypedJsonString
classe:Et puis utilisez une instance de cette classe similaire à # 1.
la source
TypedString
depuis qu'il a été supprimé?RequestBody
pour créer un corps brut.java.lang.IllegalArgumentException: Unable to create @Body converter for class MatchAPIRequestBody (parameter #1)
Au lieu de classes, nous pouvons également utiliser directement
HashMap<String, Object>
pour envoyer des paramètres de corps, par exemplela source
IllegalArgumentException: Unable to create @Body converter for java.util.HashMap<java.lang.String, java.lang.Object>
avec Moshi. Je pense que Gson est nécessaire pour que cela fonctionneOui, je sais qu'il est tard, mais quelqu'un en bénéficierait probablement.
Utilisation de Retrofit2:
J'ai rencontré ce problème la nuit dernière lors de la migration de Volley vers Retrofit2 (et comme l'indique OP, cela a été intégré à Volley avec
JsonObjectRequest
), et bien que la réponse de Jake soit la bonne pour Retrofit1.9 , Retrofit2 n'a pasTypedString
.Mon cas nécessitait l'envoi d'un
Map<String,Object>
qui pourrait contenir des valeurs nulles, converti en JSONObject (qui ne volera pas avec@FieldMap
, pas plus que les caractères spéciaux, certains ne seront convertis), donc en suivant le conseil @bnorms, et comme indiqué par Square :Il s'agit donc d'une option utilisant
RequestBody
etResponseBody
:Dans votre interface, utilisez
@Body
avecRequestBody
Dans votre point d'appel, créez un
RequestBody
, en indiquant qu'il s'agit de MediaType et en utilisant JSONObject pour convertir votre carte au format approprié:J'espère que cela aide n'importe qui!
Une élégante version Kotlin de ce qui précède, pour permettre d'abstraire les paramètres de la conversion JSON dans le reste de votre code d'application:
la source
JsonObjectRequest
, tout ce que vous devez faire est le suivant. Bonne réponse.post a null value
accéder à une propriété du requestBody qui autrement était ignorée.jsonParams.put("code", some_code);
dans la troisième ligne?Dans Retrofit2 , lorsque vous voulez envoyer vos paramètres en raw, vous devez utiliser des scalaires .
ajoutez d'abord ceci dans votre gradle:
Votre interface
Activité
la source
GsonConverterFactory
, le.toString()
n'est pas nécessaire. Vous pouvez déclarerCall<User> getUser(@Body JsonObject body);
usingJsonObject
au lieu deJSONObject
et transmettreparamObject
directement. Cela fonctionnera très bien.L'utilisation
JsonObject
est la façon dont c'est:Créez votre interface comme ceci:
Faites le JsonObject selon la structure jsons.
Appelez le service:
Et c'est son! À mon avis personnel, c'est beaucoup mieux que de faire des pojos et de travailler avec le mess de la classe. C'est beaucoup plus propre.
la source
J'aime particulièrement la suggestion de Jake concernant la
TypedString
sous - classe ci - dessus . Vous pouvez en effet créer une variété de sous-classes en fonction des types de données POST que vous prévoyez d'augmenter, chacune avec son propre ensemble personnalisé de réglages cohérents.Vous avez également la possibilité d'ajouter une annotation d'en-tête à vos méthodes JSON POST dans votre API Retrofit…
… Mais l'utilisation d'une sous-classe est plus évidemment auto-documentée.
la source
1) Ajouter des dépendances-
2) Faire de la classe Api Handler
3) Créer des classes de bean à partir du schéma Json 2 pojo
http://www.jsonschema2pojo.org/
4) faire l'interface pour appeler api
5) faire JsonObject pour passer au corps comme paramètre
6) Appelez Api comme ceci
la source
J'ai trouvé que lorsque vous utilisez un objet composé comme
@Body
paramètres, il ne pouvait pas bien fonctionner avec le RetrofitGSONConverter
(sous l'hypothèse que vous l'utilisez). Vous devez utiliserJsonObject
et nonJSONObject
lorsque vous travaillez avec cela, il ajouteNameValueParams
sans être détaillé à ce sujet - vous ne pouvez le voir que si vous ajoutez une autre dépendance de l'intercepteur de journalisation et d'autres manigances.Donc, ce que j'ai trouvé la meilleure approche pour y remédier est d'utiliser
RequestBody
. Vous transformez votre objet enRequestBody
un simple appel api et le lancez. Dans mon cas, je convertis une carte:et voici l'appel:
la source
Ajouter ScalarsConverterFactory pour moderniser:
en gradle:
votre rénovation:
changez le paramètre @Body de votre interface d'appel en String, n'oubliez pas d'ajouter
@Headers("Content-Type: application/json")
:vous pouvez maintenant publier du json brut.
la source
Vous pouvez utiliser hashmap si vous ne souhaitez pas créer de classe pojo pour chaque appel d'API.
Et puis envoyer comme ça
la source
utiliser ce qui suit pour envoyer json
et le passer à l'url
la source
Après tant d'efforts, nous avons constaté que la différence de base est que vous devez envoyer le paramètre
JsonObject
au lieu deJSONObject
.la source
Sur la base de la première réponse, j'ai une solution pour ne pas avoir à faire de POJO pour chaque demande.
Exemple, je veux publier ce JSON.
ensuite, je crée une classe commune comme celle-ci:
Enfin, quand j'ai besoin d'un json
La demande annotée
@Body
peut ensuite être transmise à Retrofit.la source
Si vous ne voulez pas créer de classes supplémentaires ou utiliser,
JSONObject
vous pouvez utiliser aHashMap
.Interface de mise à niveau:
Appel:
la source
Choses nécessaires pour envoyer du json brut dans Retrofit.
1) Assurez-vous d'ajouter l'en-tête suivant et de supprimer tout autre en-tête en double. Depuis, sur la documentation officielle de Retrofit, ils mentionnent spécifiquement-
2) a. Si vous utilisez une usine de conversion, vous pouvez passer votre json en tant que chaîne, JSONObject, JsonObject et même POJO. Ont également vérifié, avoir
ScalarConverterFactory
n'est pas seulement nécessaireGsonConverterFactory
le travail.2) b. Si vous n'utilisez PAS d'usine de convertisseur, vous DEVEZ utiliser RequestBody de okhttp3 comme la documentation de Retrofit dit-
3) Succès !!
la source
C'est ce qui me fonctionne pour la version actuelle de
retrofit
2.6.2 ,Tout d'abord, nous devons ajouter un convertisseur scalaire à la liste de nos dépendances Gradle, qui se chargerait de convertir les objets java.lang.String en corps de requête text / plain,
Ensuite, nous devons transmettre une usine de conversion à notre constructeur de rénovation. Il indiquera plus tard à Retrofit comment convertir le paramètre @Body transmis au service.
Ensuite, retrofit service avec un paramètre de corps String.
Créez ensuite le corps JSON
Appelez votre service
la source
✅✅✅✅✅✅✅✅✅✅✅✅ Solution de travail ✅✅✅✅✅✅✅✅✅✅✅✅
Lors de la création
OkHttpClient
, il sera utilisé pour la mise à niveau.ajoutez un intercepteur comme celui-ci.
Maintenant corps URL et demande d'appel à tous vos Retrofit sera connecté en
Logcat
. Filtrer par"gsonrequest"
la source
J'ai essayé ceci: lorsque vous créez votre instance Retrofit, ajoutez cette usine de conversion au générateur de modification:
la source
Résolu mon problème basé sur la réponse de TommySM (voir précédent). Mais je n'avais pas besoin de me connecter, j'ai utilisé Retrofit2 pour tester l'API https GraphQL comme ceci:
Défini ma classe BaseResponse à l'aide d'annotations json (import jackson.annotation.JsonProperty).
Défini la procédure d'appel dans l'interface:
Appelé apicall dans le corps du test: créez une variable de type MyRequest (par exemple "myLittleRequest").
la source
Pour plus de clarté sur les réponses données ici, voici comment vous pouvez utiliser les fonctions d'extension. C'est seulement si vous utilisez Kotlin
Si vous utilisez
com.squareup.okhttp3:okhttp:4.0.1
les anciennes méthodes de création d'objets de MediaType et RequestBody sont obsolètes et ne peuvent pas être utilisés dans Kotlin .Si vous souhaitez utiliser les fonctions d'extension pour obtenir un objet MediaType et un objet ResponseBody à partir de vos chaînes, ajoutez tout d'abord les lignes suivantes à la classe dans laquelle vous prévoyez de les utiliser.
Vous pouvez maintenant obtenir directement un objet de MediaType de cette façon
Pour obtenir un objet de RequestBody, convertissez d'abord le JSONObject que vous souhaitez envoyer à une chaîne de cette façon. Vous devez lui passer l'objet mediaType.
la source
Je voulais comparer la vitesse de volée et le retrofit pour envoyer et recevoir des données que j'ai écrites ci-dessous (pour la partie retrofit)
première dépendance:
Puis interface:
et une fonction pour définir les paramètres de publication des données sur le serveur (dans MainActivity):
Et j'ai trouvé Retrofit plus rapide que volley dans mon cas.
la source