Categories
curl http-headers json rest spring-mvc

How do I POST JSON data with cURL?

3535

I use Ubuntu and installed cURL on it. I want to test my Spring REST application with cURL. I wrote my POST code at the Java side. However, I want to test it with cURL. I am trying to post a JSON data. Example data is like this:

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

I use this command:

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

It returns this error:

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

The error description is this:

The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().

Tomcat log:
“POST /ui/webapp/conf/clear HTTP/1.1” 415 1051

What is the right format of the cURL command?

This is my Java side PUT code (I have tested GET and DELETE and they work):

@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;
}

3

5320

You need to set your content-type to application/json. But -d (or --data) sends the Content-Type application/x-www-form-urlencoded, which is not accepted on Spring’s side.

Looking at the curl man page, I think you can use -H (or --header):

-H "Content-Type: application/json"

Full example:

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

(-H is short for --header, -d for --data)

Note that -request POST is optional if you use -d, as the -d flag implies a POST request.


On Windows, things are slightly different. See the comment thread.

26

  • 348

    For windows, single quotes around json did not work and I ended up escaping double quotes. curl -X POST -H "Content-Type: application/json" -d "{ \"key1\": \"value1\" }" http://localhost:3000/api/method

    – hIpPy

    Sep 11, 2013 at 17:34


  • 53

    For me under Windows I needed to escape quotes using quotes in this format "{ """key1""": """value1""" }". Also this answer: stackoverflow.com/questions/18314796/…

    Jan 27, 2014 at 11:10


  • 4

    I’ve had issues with POST requests but solved it by capitalized “Application/json” so if you get a 415 error, check the capitalization.

    – Ebsan

    Apr 24, 2014 at 18:13

  • 3

    @Adam Tuttle Why does your comment have so many upvotes? With curl on ubuntu 14.04, you need "Content-Type: application/json", not just "application/json". This wasted a lot of my time…

    – ostrokach

    Oct 18, 2015 at 23:30


  • 8

    @ostrokach sorry it wasted your time. syntax worked fine for me on OSX when I posted it (haven’t retried). Guess it is/was just a platform difference. I imagine the upvotes are from people that it helped.

    Nov 1, 2015 at 1:23

689

Try to put your data in a file, say body.json and then use

curl -H "Content-Type: application/json" --data @body.json http://localhost:8080/ui/webapp/conf

10

  • 27

    You probably should use the --data-binary option instead of --data. One would expect that the client sends the data as-is, but --data strips CR und LF from the input.

    – h2stein

    Mar 24, 2014 at 8:22

  • 24

    Using cUrl with inline json Strings seems to be a nightmare. There’s the need to scape the double quote character. Going with a file like this is nicer.

    – Aritz

    Jun 26, 2014 at 10:26

  • 60

    It’s important to add an @ character before the name of the file, otherwise it won’t work. I just spent 20 minutes banging my head at this crap…

    Aug 18, 2015 at 11:41

  • 4

    This way you can also run a JSON lint on the file to see if there’s an error in parsing the JSON.

    Dec 7, 2016 at 12:37

  • 9

    On Windows, you need double quotes around the filename “@body.json”

    – Stomf

    Jun 26, 2017 at 9:28

136

For Windows, having a single quote for the -d value did not work for me, but it did work after changing to double quote. Also I needed to escape double quotes inside curly brackets.

That is, the following did not work:

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

But the following worked:

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

4

  • 6

    FYI – looks like you’re missing a closing double quote around the json body

    – acanby

    Mar 14, 2016 at 23:10


  • 4

    For me on Windows, the ” around the data does not work, no quotes works instead

    – rodedo

    Oct 17, 2016 at 9:44

  • 4

    If you’re using PowerShell, see this answer.

    – rsenna

    Feb 28, 2018 at 19:02

  • 1

    For improved quote-handling, and many other reasons, stop using the ancient/weak cmd.exe and try one of the improved shells like Git-Bash from gitforwindows.org site. (Highly recommended, even if you don’t use Git.)

    – MarkHu

    Dec 18, 2020 at 18:35