When testing my spring code with the following curl request, it fails with a http 400 bad request (The request sent by the client was syntactically incorrect.)
curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"ids":[1,2]}' <someurl>
My corresponding Spring controller has a method that looks like this
#RequestMapping(value = "someurl", method = RequestMethod.POST)
public #ResponseBody List<Result> multiple(#RequestBody List<Integer> ids){
List<Result> list = new ArrayList<>();
for(int id : ids){
// do something with id and add to result list
}
return list;
}
My url is correct, I'm almost sure my curl request is also correct, so I don't know what's wrong with my code, this is my first POST request, the GET's are all working.
EDIT:
I'm using a linux terminal
#RequestBody expects just a JSON array if used to annotate a List. You'll have to do one of two things:
Create a type to represent your POST data, with a single private List<Integer> ids field. Change your controller method signature to use that type instead of List<Integer>.
Change your JSON POST to:
curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '[1,2]' <someurl>
Either solution should work.
Related
I have a SpringBootTest class which uses SpringRunner:
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT)
public class DemoApplicationTests {
#Test
public void testCustomerList() {
get("http://localhost:8080/list")
.then()
.assertThat()
.statusCode(200)
.body("size()", is(2));
}
}
I'd like to change the accept header for the test, much like I'd do with curl:
curl --header "Accept: application/json" curl http://localhost:8080
I've tried with:
get("http://localhost:8080/list").contentType(MediaType.APPLICATION_JSON)
However I get the error "ContentType cannot be applied to Response options".
Can you recommend a way to fix it?
Thanks!
You can add accept header using accept method:
.accept(MediaType.APPLICATION_JSON_VALUE)
See also accept vs content type
Accept header is used by HTTP clients to tell the server what content types they'll accept. The server will then send back a response, which will include a Content-Type header telling the client what the content type of the returned content actually is
Seems I've figured it out.
As get is io.restassured.RestAssured.get (my apologies for not specifying it),
then it should be:
given()
.contentType("application/json").
.get("http://localhost:8080/list")
You need to specify the accept header.
get("http://localhost:8080/list")
.accept(MediaType.APPLICATION_JSON_VALUE)
.then()
.assertThat()
.statusCode(200)
.body("size()", is(2));
I have an api endpoint that I'm receiving data via a POST. My controller signature looks like this:
public function handle(Request $request)
When I go to test my endpoint, I'm running a really basic test like this:
curl -X POST -H 'Content-Type: text/xml' -d '<XML>data</XML>' http://URL/api
When I \Log::debug($request) I get nothing. Even if I \Log::debug($_POST) I still don't get anything.
Is there a filter that's turned on by default in Lumen? I'm kind of at a loss here. Maybe my curl statement is wrong?
You are sending the XML in the request body. Therefore, to retrieve the content of the request, you have to use $request->getContent like this:
public function handle(Request $request)
{
\Log::debug($request->getContent());
}
With Spring REST the request parameters are converted to an object in case you do a post, and you use #RequestBody, for example:
#RestController
#RequestMapping("/reservations")
class ReservationController{
...
#RequestMapping(value="/postByName")
public Reservation save(#RequestBody Reservation reservation) {
return reservationRepository.save(reservation);
}
...
}
Then I do, and this works fine, a Reservation is created:
curl -i -X POST -H "Content-Type:application/json" -d "{ \"name\" : \"Foo\" }" http://localhost:8080/reservations/postByName
My question is if something exists when you use path variables instead of request parameters. So I should do something like:
curl -i -X POST -H "Content-Type:application/json" http://localhost:8080/reservations/postByName/Foo
Now I do it by hand: in the code I create a Reservation with new and put the path variables in it.
The documentation says:
A #PathVariable argument can be of any simple type such as int, long, Date, etc. Spring automatically converts to the appropriate type or throws a TypeMismatchException if it fails to do so. You can also register support for parsing additional data types. See the section called “Method Parameters And Type Conversion” and the section called “Customizing WebDataBinder initialization”.
I am trying to call the ValuesController WebApi controller (that gets created by default) "PUT" method using cURL. No matter what I do, send value="abc", "abc" or "=abc" as I saw suggested in other questions for the POST method, to no avail.
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
I also tried changing the Content-Type to application/json and application/x-www-form-urlencoded, nothing seems to work.
curl -H -d "=TEST" -X PUT http://localhost:30960/api/values/5
Is this a bug in ASP.NET 5 Web Api or is there a different format I need to use when calling?
In order to make it work you need to pass it as a simple string:
"any value here"
There is even a test for this behaviour
Remember to add an application/json Content-Type header when issuing a request.
I've just tested it for both PUT and POST requests.
Using curl it's:
curl -H "Content-Type: application/json" -d "'Test'" -X PUT http://localhost:[port]/api/values/5
If you are posting data as application/x-www-form-urlencoded then you need to remove the FromBody attribute. This is a change in behavior from MVC5/WebAPI2.
If you are posting data as application/json, then you need the FromBody and also a bindable typ. Example:
public class Person
{
public string Name {get; set;}
}
for data { "Name" : "James"}
I need to use CURL as follows to invoke the API
curl http://api.somedomain.com/v1/someresource \
-d param1=3123345 \
-d param2=65098 \
-d description= “description”
How should I write the respective method? I tried with QueryParam and PathParam. But didn't worked? Need help.
You'll need a post method and your parameters are passed as form parameters:
#POST
#Path("/someresource")
#Consumes({MediaType.APPLICATION_FORM_URLENCODED})
public void someresource(#FormParam("param1") String param1, ...) {
...
}