Comment puis-je POSTER des données JSON avec cURL?

2834

J'utilise Ubuntu et y ai installé cURL . Je veux tester mon application Spring REST avec cURL. J'ai écrit mon code POST côté Java. Cependant, je veux le tester avec cURL. J'essaie de publier des données JSON. Les données d'exemple sont comme ceci:

{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}

J'utilise cette commande:

curl -i \
    -H "Accept: application/json" \
    -H "X-HTTP-Method-Override: PUT" \
    -X POST -d "value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true \
    http://localhost:8080/xx/xxx/xxxx

Il renvoie cette erreur:

HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 1051
Date: Wed, 24 Aug 2011 08:50:17 GMT

La description de l'erreur est la suivante:

Le serveur a refusé cette demande car l'entité de demande est dans un format non pris en charge par la ressource demandée pour la méthode demandée ().

Journal Tomcat: "POST / ui / webapp / conf / clear HTTP / 1.1" 415 1051

Quel est le bon format de la commande cURL?

Voici mon PUTcode latéral Java (j'ai testé GET et DELETE et ils fonctionnent):

@RequestMapping(method = RequestMethod.PUT)
public Configuration updateConfiguration(HttpServletResponse response, @RequestBody Configuration configuration) { //consider @Valid tag
    configuration.setName("PUT worked");
    //todo If error occurs response.sendError(HttpServletResponse.SC_NOT_FOUND);
    return configuration;
}
kamaci
la source
6
consultez le lien pour les demandes de publication du printemps 3.2.0.
AmirHd
8
Il y a un bon article sur l' utilisation de Curl pour les tests ad hoc des microservices RESTful qui couvre cela avec de nombreux exemples.
upitau

Réponses:

4342

Vous devez définir votre type de contenu sur application / json. Mais -denvoie le Content-Type application/x-www-form-urlencoded, qui n'est pas accepté du côté de Spring.

En regardant la page de manuel curl , je pense que vous pouvez utiliser-H :

-H "Content-Type: application/json"

Exemple complet:

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"username":"xyz","password":"xyz"}' \
  http://localhost:3000/api/login

( -Hest l'abréviation de--header , -dpour --data)

Notez que cela -request POSTest facultatif si vous utilisez-d , car l' -dindicateur implique une demande POST.


Sous Windows, les choses sont légèrement différentes. Voir le fil de commentaires.

Sean Patrick Floyd
la source
262
Pour Windows, les guillemets simples autour de json ne fonctionnaient pas et j'ai fini par échapper aux guillemets doubles. curl -X POST -H "Content-Type: application/json" -d "{ \"key1\": \"value1\" }" http://localhost:3000/api/method
hIpPy
37
Pour moi, sous Windows, j'avais besoin d'échapper aux guillemets en utilisant des guillemets dans ce format "{ """key1""": """value1""" }". Aussi cette réponse: stackoverflow.com/questions/18314796/…
chodorowicz
4
@chodorowicz c'est affreux! Je connais seulement cette syntaxe de VB!
Sean Patrick Floyd
3
J'ai eu des problèmes avec les requêtes POST mais je les ai résolus en mettant en majuscule "Application / json", donc si vous obtenez une erreur 415, vérifiez la capitalisation.
WiteCastle
5
@ostrokach désolé, vous avez perdu votre temps. la syntaxe a bien fonctionné pour moi sur OSX lorsque je l'ai posté (je n'ai pas réessayé). Je suppose que c'est / était juste une différence de plate-forme. J'imagine que les votes positifs proviennent de personnes que cela a aidé.
Adam Tuttle
565

Essayez de mettre vos données dans un fichier, dites body.json, puis utilisez

curl -H "Content-Type: application/json" --data @body.json http://localhost:8080/ui/webapp/conf
Typisch
la source
12
Vous devriez probablement utiliser l' --data-binaryoption au lieu de --data. On peut s'attendre à ce que le client envoie les données telles quelles, mais --datasupprime CR et LF de l'entrée.
h2stein
14
L'utilisation de cUrl avec des chaînes json en ligne semble être un cauchemar. Il est nécessaire de scape le caractère double guillemet. Aller avec un fichier comme celui-ci est plus agréable.
Xtreme Biker
46
Il est important d'ajouter un @caractère avant le nom du fichier, sinon cela ne fonctionnera pas. Je viens de passer 20 minutes à me cogner la tête à cette merde ...
Radu Murzea
3
De cette façon, vous pouvez également exécuter un lint JSON sur le fichier pour voir s'il y a une erreur dans l'analyse du JSON.
datashaman
4
Sous Windows, vous avez besoin de guillemets doubles autour du nom de fichier "@ body.json"
Stomf
100

Vous pourriez trouver resty utile: https://github.com/micha/resty

Il s'agit d'un wrapper round CURL qui simplifie les demandes REST en ligne de commande. Vous le pointez vers votre point de terminaison API et il vous donne des commandes PUT et POST. (Exemples adaptés de la page d'accueil)

$ resty http://127.0.0.1:8080/data #Sets up resty to point at your endpoing
$ GET /blogs.json                  #Gets http://127.0.0.1:8080/data/blogs.json
                                   #Put JSON
$ PUT /blogs/2.json '{"id" : 2, "title" : "updated post", "body" : "This is the new."}'
                                   # POST JSON from a file
$ POST /blogs/5.json < /tmp/blog.json

De plus, il est souvent toujours nécessaire d'ajouter les en-têtes de type de contenu. Vous pouvez le faire une fois, cependant, pour définir une valeur par défaut, pour ajouter des fichiers de configuration par méthode et par site: Définition des options RESTY par défaut

mo-seph
la source
93

Pour Windows, avoir un seul devis pour la -dvaleur n'a pas fonctionné pour moi, mais cela a fonctionné après être passé à un double devis. J'ai également eu besoin d'échapper aux guillemets doubles entre crochets.

Autrement dit, les éléments suivants n'ont pas fonctionné:

curl -i -X POST -H "Content-Type: application/json" -d '{"key":"val"}' http://localhost:8080/appname/path

Mais ce qui suit a fonctionné:

curl -i -X POST -H "Content-Type: application/json" -d "{\"key\":\"val\"}" http://localhost:8080/appname/path
venkatnz
la source
5
Pour info - on dirait que vous manquez une double citation de fermeture autour du corps de json
acanby
3
Pour moi sur Windows, le "autour des données ne fonctionne pas, aucune citation ne fonctionne à la place
rodedo
3
Si vous utilisez PowerShell, consultez cette réponse.
rsenna
86

Cela a fonctionné pour moi en utilisant:

curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":100}' http://localhost/api/postJsonReader.do

Il a été heureusement mappé au contrôleur Spring:

@RequestMapping(value = "/postJsonReader", method = RequestMethod.POST)
public @ResponseBody String processPostJsonData(@RequestBody IdOnly idOnly) throws Exception {
        logger.debug("JsonReaderController hit! Reading JSON data!"+idOnly.getId());
        return "JSON Received";
}

IdOnlyest un POJO simple avec une propriété id.

Luis
la source
56

Par exemple, créez un fichier JSON, params.json, et ajoutez-y ce contenu:

[
    {
        "environment": "Devel",
        "description": "Machine for test, please do not delete!"
    }
]

Ensuite, vous exécutez cette commande:

curl -v -H "Content-Type: application/json" -X POST --data @params.json -u your_username:your_password http://localhost:8000/env/add_server
Eduardo Cerqueira
la source
42

Je viens de rencontrer le même problème. Je pourrais le résoudre en spécifiant

-H "Content-Type: application/json; charset=UTF-8"
Steffen Roller
la source
37

Cela a bien fonctionné pour moi.

curl -X POST --data @json_out.txt http://localhost:8080/

Où,

-X Signifie le verbe http.

--data Désigne les données que vous souhaitez envoyer.

felipealvesgnu
la source
5
Le -X POSTest redondant dans cet exemple
Ingénieur logiciel
31

Vous pouvez utiliser Postman avec son interface graphique intuitive pour assembler votre cURLcommande.

  1. Installer et démarrer Postman
  2. Saisissez votre URL, le corps du message, les en-têtes de demande, etc. pp.
  3. Cliquer sur Code
  4. Sélectionnez cURLdans la liste déroulante
  5. copiez et collez votre cURLcommande

Remarque: Il existe plusieurs options pour la génération automatisée de demandes dans la liste déroulante, c'est pourquoi j'ai pensé que mon message était nécessaire en premier lieu.

kiltek
la source
6
Je ne savais pas que cette fonctionnalité était incluse dans Postman. Merci de l'avoir signalé!
ariestav
29

En utilisant CURL Windows, essayez ceci:

curl -X POST -H "Content-Type:application/json" -d "{\"firstName\": \"blablabla\",\"lastName\": \"dummy\",\"id\": \"123456\"}" http-host/_ah/api/employeeendpoint/v1/employee
Márcio Brener
la source
28

Vous pouvez utiliser postman pour convertir en CURLentrez la description de l'image ici

entrez la description de l'image ici

octet mamba
la source
1
Merci beaucoup @ forever-LA, c'était un conseil qui m'a
sauvé la vie
24

HTTPie est une alternative recommandée curlcar vous pouvez faire simplement

$ http POST http://example.com/some/endpoint name=value name1=value1

Il parle JSON par défaut et gérera à la fois la définition de l'en-tête nécessaire pour vous ainsi que l'encodage des données en tant que JSON valide. Il y a aussi:

Some-Header:value

pour les en-têtes, et

name==value

pour les paramètres de chaîne de requête. Si vous avez un gros morceau de données, vous pouvez également le lire à partir d'un fichier qu'il soit encodé en JSON:

 field=@file.txt
tosh
la source
20

Si vous testez de nombreux envois / réponses JSON par rapport à une interface RESTful, vous pouvez consulter le plug-in Postman pour Chrome (qui vous permet de définir manuellement les tests de service Web) et sa commande Newman basée sur Node.js. compagnon en ligne (qui vous permet d'automatiser les tests par rapport aux "collections" de tests Postman.) Gratuit et ouvert!

ftexperts
la source
18

Cela a bien fonctionné pour moi, en plus d'utiliser l'authentification BASIC:

curl -v --proxy '' --basic -u Administrator:password -X POST -H "Content-Type: application/json"
        --data-binary '{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}'
        http://httpbin.org/post

Bien sûr, vous ne devez jamais utiliser l'authentification BASIC sans SSL et un certificat vérifié.

J'ai rencontré cela de nouveau aujourd'hui, en utilisant cURL 7.49.1 de Cygwin pour Windows ... Et lorsque vous utilisez --dataou --data-binaryavec un argument JSON, cURL est devenu confus et interpréterait {}le JSON comme un modèle d'URL. L'ajout d'un -gargument pour désactiver la globalisation cURL a corrigé cela.

Voir aussi Passer une URL avec des crochets pour boucler .

davenpcj
la source
17

Vous pouvez également mettre votre contenu JSON dans un fichier et le transmettre à curl en utilisant l' --file-uploadoption via une entrée standard, comme ceci:

 echo 'my.awesome.json.function({"do" : "whatever"})' | curl -X POST "http://url" -T -
niken
la source
16

Cela a fonctionné pour moi:

curl -H "Content-Type: application/json" -X POST -d @./my_json_body.txt http://192.168.1.1/json
Amit Vujic
la source
10

J'utilise le format ci-dessous pour tester avec un serveur Web.

use -F 'json data'

Supposons ce format de dict JSON:

{
    'comment': {
        'who':'some_one',
        'desc' : 'get it'
    }
}

Exemple complet

curl -XPOST your_address/api -F comment='{"who":"some_one", "desc":"get it"}'
user3180641
la source
6

Utilisez l'option -d pour ajouter une charge utile

curl -X POST \
http://<host>:<port>/<path> \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"foo": "bar",
"lorem": "ipsum"
}'

En plus:

utiliser -X POST pour utiliser la méthode POST

utilisez -H 'Accept: application / json' pour ajouter un en-tête de type accept

utilisez -H 'Content-Type: application / json' pour ajouter un en-tête de type de contenu

Sma Ma
la source
J'ai essayé de l'utiliser, mais j'ai obtenu une erreur "{" errors ": [" no data provided "]}}.
Suresh
6

Veuillez vérifier cet outil . Il vous aide à créer facilement des extraits de boucles.

curl -XGET -H "Accept: application/json" -d "{\"value\":\"30\",\"type\":\"Tip 3\",\"targetModule\":\"Target 3\",\"configurationGroup\":null,\"name\":\"Configuration Deneme 3\",\"description\":null,\"identity\":\"Configuration Deneme 3\",\"version\":0,\"systemId\":3,\"active\":true}" "http://localhost:8080/xx/xxx/xxxx"
Pranay Kumar
la source
6

Cela a fonctionné pour moi sur Windows10

curl -d "{"""owner""":"""sasdasdasdasd"""}" -H "Content-Type: application/json" -X  PUT http://localhost:8080/api/changeowner/CAR4
sudhanshu srivastava
la source
5

Voici une autre façon de le faire, si vous avez des données dynamiques à inclure.

#!/bin/bash

version=$1
text=$2
branch=$(git rev-parse --abbrev-ref HEAD)
repo_full_name=$(git config --get remote.origin.url | sed 's/.*:\/\/github.com\///;s/.git$//')
token=$(git config --global github.token)

generate_post_data()
{
  cat <<EOF
{
  "tag_name": "$version",
  "target_commitish": "$branch",
  "name": "$version",
  "body": "$text",
  "draft": false,
  "prerelease": false
}
EOF
}

echo "Create release $version for repo: $repo_full_name branch: $branch"
curl --data "$(generate_post_data)" "https://api.github.com/repos/$repo_full_name/releases?access_token=$token"
Anand Rockzz
la source
1
Tu m'as sauvé la vie!
Abhimanyu
4

Je sais, beaucoup a été répondu à cette question, mais je voulais partager où j'ai eu le problème de:

curl -X POST http: // votre-point-de-fin-de-serveur -H "Content-Type: application / json" -d @ chemin-de-votre-fichier-json.json

Vous voyez, j'ai tout fait correctement, une seule chose - "@" j'ai raté avant le chemin du fichier JSON.

J'ai trouvé un document de référence pertinent sur Internet - https://gist.github.com/subfuzion/08c5d85437d5d4f00e58

J'espère que cela pourrait aider quelques-uns. Merci

Tu es incroyable
la source
1

Si vous configurez SWAGGER sur votre application Spring Boot et appelez n'importe quelle API à partir de votre application, vous pouvez également voir cette demande CURL.

Je pense que c'est le moyen facile de générer les demandes via le CURL.

AnilkumarReddy
la source