How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?

kamaci Source

I use Ubuntu and installed Curl on it. I want to test my Spring REST application with Curl. I wrote my POST code at Java side. However, I want to test it with Curl. I am trying to post a JSON data. An 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

Any ideas about the right format of the Curl command?

EDIT:

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;
} 
jsonrestspring-mvccurl

Answers

answered 7 years ago Sean Patrick Floyd #1

You need to set your content-type to application/json. But -d 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:

-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.

answered 7 years ago Typisch #2

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

answered 7 years ago Steffen Roller #3

I just run into the same problem. I could solve it by specifying

-H "Content-Type: application/json; charset=UTF-8"

answered 7 years ago mo-seph #4

You might find resty useful: https://github.com/micha/resty

It's a wrapper round CURL which simplifies command line REST requests. You point it to your API endpoint, and it gives you PUT and POST commands. (Examples adapted from the homepage)

$ 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

Also, it's often still necessary to add the Content Type headers. You can do this once, though, to set a default, of add config files per-method per-site: Setting default RESTY options

answered 6 years ago Luis #5

It worked for me using:

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

It was happily mapped to the Spring controller:

@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 is a simple POJO with an id property.

answered 5 years ago davenpcj #6

This worked well for me, additionally using BASIC authentication:

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

Of course, you should never use BASIC authentication without SSL and a checked certificate.

I ran into this again today, using Cygwin's cURL 7.49.1 for Windows... And when using --data or --data-binary with a JSON argument, cURL got confused and would interpret the {} in the JSON as a URL template. Adding a -g argument to turn off cURL globbing fixed that.

See also Passing a URL with brackets to curl.

answered 5 years ago user3180641 #7

I am using the below format to test with a web server.

use -F 'json data'

Let's assume this JSON dict format:

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

Full example

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

answered 4 years ago ftexperts #8

If you're testing a lot of JSON send/responses against a RESTful interface, you may want to check out the Postman plug-in for Chrome (which allows you to manually define web service tests) and its Node.js-based Newman command-line companion (which allows you to automate tests against "collections" of Postman tests.) Both free and open!

answered 4 years ago venkatnz #9

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

answered 4 years ago Márcio Brener #10

Using CURL Windows, try this:

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

answered 3 years ago felipealves.gnu #11

This worked well for me.

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

Where,

-X Means the http verb.

--data Means the data you want to send.

answered 3 years ago Eduardo Cerqueira #12

As an example, create a JSON file, params.json, and add this content to it:

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

Then you run this command:

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

answered 2 years ago Amit Vujic #13

This worked for me:

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

answered 1 year ago iloveretards #14

A bit late to the party, but I don't see this posted, so here goes, you could also put your json in a file and pass it to curl using --file-upload option via standard input, like this:

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

answered 11 months ago kiltek #15

You can use Postman with its intuitive GUI to assemble your cURL command.

  1. Install and Start Postman
  2. Type in your URL, Post Body, Request Headers etc. pp.
  3. Click on Code
  4. Select cURL from the drop-down list
  5. copy & paste your cURL command

Note: There are several options for automated request generation in the drop-down list, which is why I thought my post was neccessary in the first place.

answered 10 months ago Vishvajit Pathak #16

For json data

curl -H "Content-Type: application/json" -X POST -d '{"params1":"value1","param2":"value2"}' http://localhost:8080/api

If you want to post some file

curl -X POST -F "[email protected]/Users/vishvajitpathak/Desktop/screen_1.png" http://localhost:8080/upload --insecure

In case you dont want to mess up with https and http:

OR Simply,

curl -X POST -F "[email protected]/Users/vishvajitpathak/Desktop/screen_1.png" http://localhost:8080/upload

answered 9 months ago tosh #17

There is awesome HTTPie CLI tool. With it, you can do just

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

and so on, and no worries. There is also

Some-Header:value

for headers, and

name==value

for query string parameters.

P.S.

IMHO, the only valid usage of curl is downloading something without persisting it, and just piping it right away to next filter. Example:

$ curl -sSL https://example.com/archive.tar.gz |tar -xzf - - you don't need to persist file if all what you want is to immediately expand it.

$ curl -sSL https://exapmle.com/script.sh |bash - same, again, but with shell script (don't do that EVER, though).

Note, however, that by "curl" I mean command line utility, not the library. Library awesome by its own. But, it is also why cli tool is not so usable and handy.

The best utility to just download file and persist it with same name as remote is wget (1) (or aria2). Period. Please, don't use curl for this. When you do that, a little pretty kitty dies somewhere in the world.

The bet utility to deal with requests when you develop some king of web service (REST API, XML RPC, anything) is HTTPie. Period.

answered 7 months ago Suchi #18

I use JSON in my application and its simple as :

curl -X POST -H "Content-Type:application/json" -d '{"params1":"value1","params2":"value2"} hostname:port/api

But if you have a large number of params always prefer to use a file with the JSON request body as below:

curl -X POST -H "Content-Type:application/json" -F "[email protected]/users/suchi/dekstop/JSON_request.txt" hostname:port/api

answered 1 month ago Saurabh Oza #19

You can pass the extension of the format you want as the end of the url. like http://localhost:8080/xx/xxx/xxxx.json

or

http://localhost:8080/xx/xxx/xxxx.xml

Note: you need to add jackson and jaxb maven dependencies in your pom.

comments powered by Disqus