Como POSTAR dados JSON com cURL?

2833

Eu uso o Ubuntu e instalei o cURL nele. Quero testar meu aplicativo Spring REST com cURL. Eu escrevi meu código POST no lado Java. No entanto, quero testá-lo com cURL. Estou tentando postar dados JSON. Os dados de exemplo são assim:

{"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}

Eu uso este comando:

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

Retorna este erro:

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

A descrição do erro é esta:

O servidor recusou esta solicitação porque a entidade da solicitação está em um formato não suportado pelo recurso solicitado para o método solicitado ().

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

Qual é o formato correto do comando cURL?

Este é o meu PUTcódigo lateral Java (eu testei GET e DELETE e eles funcionam):

@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
fonte
6
confira o link para solicitações de postagem da primavera 3.2.0.
precisa saber é o seguinte
8
Há um bom post Usando o Curl para testes ad hoc de microsserviços RESTful, que aborda isso com vários exemplos.
upitau 28/08/16

Respostas:

4342

Você precisa definir seu tipo de conteúdo como application / json. Mas -denvia o tipo de conteúdo application/x-www-form-urlencoded, que não é aceito no lado do Spring.

Olhando para a página de manual curl , acho que você pode usar -H:

-H "Content-Type: application/json"

Exemplo completo:

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

( -Hé abreviação de --header, -dpara --data)

Observe que isso -request POSTé opcional se você usar -d, pois o -dsinalizador implica uma solicitação POST.


No Windows, as coisas são um pouco diferentes. Veja o tópico do comentário.

Sean Patrick Floyd
fonte
262
Para o Windows, aspas simples em torno de json não funcionaram e acabei escapando de aspas duplas. curl -X POST -H "Content-Type: application/json" -d "{ \"key1\": \"value1\" }" http://localhost:3000/api/method
HIpPy
37
Para mim, no Windows, eu precisava escapar de aspas usando aspas neste formato "{ """key1""": """value1""" }". Também esta resposta: stackoverflow.com/questions/18314796/…
chodorowicz
4
@chodorowicz isso é horrível! Eu só conheço essa sintaxe do VB!
Sean Patrick Floyd
3
Eu tive problemas com solicitações POST, mas resolvi com "Application / json" maiúsculo. Se você receber um erro 415, verifique a capitalização.
WiteCastle
5
@ostrokach desculpe, perdeu seu tempo. sintaxe funcionou bem para mim no OSX quando eu postei (não tentei novamente). Acho que é / foi apenas uma diferença de plataforma. Eu imagino que os votos positivos são de pessoas que ajudaram.
Adam Tuttle
565

Tente colocar seus dados em um arquivo, diga body.jsone use

curl -H "Content-Type: application/json" --data @body.json http://localhost:8080/ui/webapp/conf
Typisch
fonte
12
Você provavelmente deve usar a --data-binaryopção em vez de --data. Seria de esperar que o cliente envie os dados como estão, mas --dataretira CR e LF da entrada.
h2stein
14
Usar cUrl com json Strings embutido parece ser um pesadelo. Há a necessidade de escapar do caractere de aspas duplas. Indo com um arquivo como este é melhor.
Xtreme Biker
46
É importante adicionar um @caractere antes do nome do arquivo, caso contrário não funcionará. Eu passei apenas 20 minutos batendo a cabeça no essa porcaria ...
Radu Murzea
3
Dessa forma, você também pode executar um JSON lint no arquivo para verificar se há um erro na análise do JSON.
Datashaman 07/12/16
4
No Windows, você precisa de aspas duplas ao redor do nome do arquivo "@ body.json"
Stomf 26/06/17
100

Você pode achar bastante útil: https://github.com/micha/resty

É um wrapper round CURL que simplifica as solicitações REST da linha de comando. Você o aponta para o terminal da API e fornece os comandos PUT e POST. (Exemplos adaptados da página inicial)

$ 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

Além disso, muitas vezes ainda é necessário adicionar os cabeçalhos do tipo de conteúdo. Você pode fazer isso uma vez, no entanto, para definir um padrão, para adicionar arquivos de configuração por método por site: Definindo opções padrão de RESTY

mo-seph
fonte
93

Para o Windows, ter uma citação única para o -dvalor não funcionou para mim, mas funcionou após a alteração para aspas duplas. Também precisava escapar de aspas duplas dentro de colchetes.

Ou seja, o seguinte não funcionou:

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

Mas o seguinte funcionou:

curl -i -X POST -H "Content-Type: application/json" -d "{\"key\":\"val\"}" http://localhost:8080/appname/path
venkatnz
fonte
5
FYI - Parece que você está faltando um aspas duplas fechando em torno do corpo json
acanby
3
Para mim, no Windows, o "em torno dos dados não funcionar, sem aspas funciona em vez
rodedo
3
Se você estiver usando o PowerShell, consulte esta resposta.
rsenna
86

Funcionou para mim usando:

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

Felizmente, foi mapeado para o controlador 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";
}

IdOnlyé um POJO simples com uma propriedade id.

Luis
fonte
56

Como exemplo, crie um arquivo JSON, params.json, e adicione este conteúdo a ele:

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

Então você executa este comando:

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
fonte
42

Acabei de encontrar o mesmo problema. Eu poderia resolvê-lo especificando

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

Isto funcionou bem para mim.

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

Onde,

-X Significa o verbo http.

--data Significa os dados que você deseja enviar.

felipealvesgnu
fonte
5
A -X POSTé redundante neste exemplo
Software Engineer
31

Você pode usar o Postman com sua GUI intuitiva para montar seu cURLcomando.

  1. Instalar e iniciar o Postman
  2. Digite seu URL, corpo da postagem, cabeçalhos de solicitação etc. pp.
  3. Clique em Code
  4. Selecione cURLna lista suspensa
  5. copie e cole seu cURL comando

Nota: Existem várias opções para geração automatizada de solicitações na lista suspensa, razão pela qual pensei que minha postagem era necessária em primeiro lugar.

Kiltek
fonte
6
Não sabia que esse recurso estava incluído no Postman. Obrigado por apontar isso!
ariestav
29

Usando o CURL Windows, tente o seguinte:

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
fonte
28

Você pode usar o carteiro para converter em CURLinsira a descrição da imagem aqui

insira a descrição da imagem aqui

byte mamba
fonte
1
Muito obrigado @ para sempre-LA era uma dica salva-vidas para mim
vibs2006
24

HTTPie é uma alternativa recomendada curlporque você pode fazer apenas

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

Ele fala JSON por padrão e manipula a configuração do cabeçalho necessário para você, assim como a codificação de dados como JSON válido. Há também:

Some-Header:value

para cabeçalhos e

name==value

para parâmetros de string de consulta. Se você possui uma grande quantidade de dados, também pode lê-los em um arquivo, se estes estiverem codificados em JSON:

 field=@file.txt
tosh
fonte
20

Se você estiver testando muitas respostas / envios JSON em uma interface RESTful, consulte o plug-in Postman para Chrome (que permite definir manualmente os testes de serviço da web) e seu comando Newman baseado em Node.js. companheiro de linha (que permite automatizar testes contra "coleções" de testes do Postman.) Gratuito e aberto!

ftexperts
fonte
18

Isso funcionou bem para mim, usando adicionalmente a autenticação 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

Obviamente, você nunca deve usar autenticação BASIC sem SSL e um certificado verificado.

Encontrei isso novamente hoje, usando o cURL 7.49.1 do Cygwin para Windows ... E ao usar --dataou --data-binarycom um argumento JSON, o cURL ficou confuso e interpretaria o {}no JSON como um modelo de URL. Adicionando um-g argumento para desativar o cURL globbing corrigiu isso.

Consulte também Passando um URL com colchetes para enrolar .

davenpcj
fonte
17

Você também pode colocar seu conteúdo JSON em um arquivo e passá-lo para curl usando a --file-uploadopção via entrada padrão, desta forma:

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

Isso funcionou para mim:

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

Estou usando o formato abaixo para testar com um servidor web.

use -F 'json data'

Vamos assumir este formato de ditado JSON:

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

Exemplo completo

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

Use a opção -d para adicionar carga útil

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

Além do que, além do mais:

use -X POST para usar o método POST

use -H 'Accept: application / json' para adicionar um cabeçalho de tipo de aceitação

use -H 'Content-Type: application / json' para adicionar cabeçalho do tipo de conteúdo

Sma Ma
fonte
Tentei usá-lo, mas obtendo erro "{" errors ": [" no data included "]}.
Suresh
6

Por favor, verifique esta ferramenta . Ajuda você a criar facilmente snippets de ondulação.

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
fonte
6

Isso funcionou para mim no Windows10

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

Aqui está outra maneira de fazer isso, se você tiver dados dinâmicos a serem incluídos.

#!/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
fonte
1
Você salvou minha vida!
Abhimanyu
4

Sei que muito foi respondido a essa pergunta, mas queria compartilhar onde eu tinha o problema de:

curl -X POST http: // ponto final do seu servidor -H "Tipo de conteúdo: application / json" -d @ caminho-do-seu-json-arquivo.json

Veja, fiz tudo certo. Apenas uma coisa - "@" perdi antes do caminho do arquivo JSON.

Encontrei um documento relevante na internet - https://gist.github.com/subfuzion/08c5d85437d5d4f00e58

Espero que ajude poucos. obrigado

Você é demais
fonte
1

Se você configurar o SWAGGER para o aplicativo de inicialização do Spring e chamar qualquer API do seu aplicativo, poderá ver a solicitação CURL também.

Eu acho que essa é a maneira mais fácil de gerar solicitações através do CURL.

AnilkumarReddy
fonte