multiple - How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
curl post json php (14)
HTTPie is a recommended alternative to curl
because you can do just
$ http POST http://example.com/some/endpoint name=value name1=value1
It speaks JSON by default and will handle both setting the necessary header for you as well encoding data as valid JSON. There is also:
Some-Header:value
for headers, and
name==value
for query string parameters. If you have a large chunk of data, you can also read it from a file have it be JSON encoded:
[email protected]
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;
}
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 -
Create JSON file "MyData.json" and add content:
[
{
"Key_one": "Value_one",
"Key_two": "Value_two",
"Key_three": "Value_three"
}
]
After this, you need to run following command:
curl -v -H "Content-Type: application/json" -X POST --data @MyData.json -u USERNAME:PASSWORD http://localhost:8000/env/add_server
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
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"}'
I just run into the same problem. I could solve it by specifying
-H "Content-Type: application/json; charset=UTF-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!
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.
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.
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.
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
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.
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
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.