3

This is my java code:

@POST
@Path("/sumPost")
@Produces(MediaType.TEXT_PLAIN)
public String sumPost(@QueryParam(value = "x") int x,
        @QueryParam(value = "y") int y) {
    System.out.println("x = " + x);
    System.out.println("y = " + y);
    return (x + y) + "\n";
}

I call it like this:

curl -XPOST "http://localhost:8080/CurlServer/curl/curltutorial/sumPost" -d 'x:5&y:3'

The problem is the System.out.println call keeps posting zero zero, it seems I am not passing x and y correctly.

Update

After the answer, I changed my request to:

curl   -d '{"x" : 4, "y":3}'  "http://localhost:8080/CurlServer/curl/curltutorial/sumPost" -H "Content-Type:application/json" -H "Accept:text/plain"  --include

and the service is:

@POST
@Path("/sumPost")
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.APPLICATION_JSON)
public String sumPost(@QueryParam(value = "x") int x,
        @QueryParam(value = "y") int y) {
    System.out.println("sumPost");
    System.out.println("x = " + x);
    System.out.println("y = " + y);
    return (x + y) + "\n";
}

but I still have the same problem. Here is the response from the server:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/plain
Transfer-Encoding: chunked
Date: Wed, 23 Sep 2015 11:12:38 GMT

0

You can see the zero at the end :(

approxiblue
  • 6,982
  • 16
  • 51
  • 59
Marco Dinatsoli
  • 10,322
  • 37
  • 139
  • 253

3 Answers3

5

-d x=1&y=2 (notice the =, not :) is form data (application/x-www-form-urlencoded) sent it the body of the request, in which your resource method should look more like

@POST
@Path("/sumPost")
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String sumPost(@FormParam("x") int x,
                      @FormParam("y") int y) {

}

and the following request would work

curl -XPOST "http://localhost:8080/CurlServer/curl/curltutorial/sumPost" -d 'x=5&y=3'

Note: With Windows, double quotes are required ("x=5&y=3")

You could even separate the key value pairs

curl -XPOST "http://localhost:8080/..." -d 'x=5' -d 'y=3'

The default Content-Type is application/x-www-form-urlencoded, so you don't need to set it.

@QueryParams are supposed to be part of the query string (part of the URL), not part of the body data. So your request should be more like

curl "http://localhost:8080/CurlServer/curl/curltutorial/sumPost?x=1&y=2"

With this though, since you are not sending any data in the body, you should probably just make the resource method a GET method.

@GET
@Path("/sumPost")
@Produces(MediaType.TEXT_PLAIN)
public String sumPost(@QueryParam("x") int x,
                      @QueryParam("y") int y) {
}

If you wanted to send JSON, then your best bet is to make sure you have a JSON provider[1] that handle deserializing to a POJO. Then you can have something like

public class Operands {
    private int x;
    private int y;
    // getX setX getY setY
}
...
@POST
@Path("/sumPost")
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.APPLICATION_JSON)
public String sumPost(Operands ops) {

}

[1]- The important thing is that you do have a JSON provider. If you don't have one, you will get an exception with a message like "No MessageBodyReader found for mediatype application/json and type Operands". I would need to know what Jersey version and if you are using Maven or not, to able to determine how you should add JSON support. But for general information you can see

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • before answering your questions, i need to be clear, you said: `since you are not sending any data in the body, you should probably just make the resource method a GET method.` but wait, i am sending post request, that means the `x` and `y` parameters are in the body not in the header, right? – Marco Dinatsoli Sep 24 '15 at 08:46
  • Maybe what I should've said is _"since the resource method is not expecting any data in the body"_. You have no method parameters to accept a body. Generally a method argument to accept a body has no annotations. In most cases that is how it is known to be the entity body (the exception to the case being form data). In your case the data is expected to come in the URL (`@QueryParam`) – Paul Samsotha Sep 24 '15 at 08:48
  • okay it is obvious that i made a mistake using queryparam, i didn't know that queryparam is for url. but if i change it to form param will that mean that the x and y are in the body of the http request ? – Marco Dinatsoli Sep 24 '15 at 09:02
  • Yes. And with `-d`, that sends it in the body. Then the first example is what you would go with. – Paul Samsotha Sep 24 '15 at 09:04
  • do I understand that `-d '{"x":3, "y":4}'` doesn't mean that the request is json? plus one for now – Marco Dinatsoli Sep 24 '15 at 09:10
  • The data _is_ in valid JSON format, but the only way the server knows it's JSON and process it as such is with the `Content-Type: application/json` header. With cURL the default content type is `application/x-www-form-urlencoded`. So if you send form data, as in the first example, the `Content-Type` is not needed. – Paul Samsotha Sep 24 '15 at 09:12
  • Just setting the `Content-Type: application/json` is still not enough for Jersey. It needs to have a provider that knows how to turn `application/json` data to other types. It knows how to convert it to `String`. That is trivial. So you can have a `String` method parameter. But if you want the JSON to automatically be converted to `Operands`, then you need a provider to handle it. – Paul Samsotha Sep 24 '15 at 09:15
  • are you saying that if i want to send JSON, the signature of the method should be like this `public string receiveJSON(@formpart("x") String jsonString) {}` and then i parse the string to get the actual values ? – Marco Dinatsoli Sep 25 '15 at 08:52
0

You are missing the data part of the command:

curl --data "param1=value1&param2=value2" https://example.com/fakesite.php

The -d (or --data) should come before the link. And the "name value pair" should be varName=varValue&otherVar=otherValue

Also, from documentation, the -X command is not correct:

This option only changes the actual word used in the HTTP request, it does not alter the way curl behaves. So for example if you want to make a proper HEAD request, using -X HEAD will not suffice. You need to use the -I, --head option. 

It should be -X POST

Finally, Remember to use "html encode" to encode your values.

Bonatti
  • 2,778
  • 5
  • 23
  • 42
  • `-d` is the short form for `--data` and (either) changes the verb to `POST` so you don't need `-X` (although it doesn't hurt). The key is to put it before the URL as you say, and use `=`. If you use `--data-urlencode` curl does URL encoding for you. (Not HTML entities, which are like `"` and ` ` and are not used on input only output.) – dave_thompson_085 Sep 22 '15 at 12:34
  • @dave_thompson_085 my mistake, I confused the 2 commands, will fix on answer – Bonatti Sep 22 '15 at 12:38
  • according to your answer, the request should be `curl -X POST -d "x=4&y=2" "http://localhost:8080/CurlServer/curl/curltutorial/sumPost"` but i still have the same problem – Marco Dinatsoli Sep 23 '15 at 10:55
  • @MarcoDinatsoli Edit your question, post the content of: `http://localhost:8080/CurlServer/curl/curltutorial/sumPost ` Access with your browser, and check that the link works as expected. Then, post the access log from the server, showing that the request is correct (200 code, from Browser AND from application). Finally show the result of: `curl --data "x=4&y=2" http://localhost:8080/CurlServer/curl/curltutorial/sumPost` Copy/Paste as shown here...the URL+URI should NOT be within `"` – Bonatti Sep 23 '15 at 14:43
  • @Bonatti i already did all of that, four hours ago, please check my update. – Marco Dinatsoli Sep 23 '15 at 14:49
  • @MarcoDinatsoli And where is the access.log, also, give more details on what your server is, and what module/file extension/whatever is the sumpost... – Bonatti Sep 23 '15 at 15:10
  • @Bonatti my friend, I gave you the code, and what I have tried and the response from the server. If you think my code is correct, kindly tell me, so we know that the problem is somewhere else. Then, I can give you the log. – Marco Dinatsoli Sep 23 '15 at 15:13
  • @MarcoDinatsoli As far as I can tell, your localhost is a local web server. I am guessing Apache (it makes a world of difference what webserver you are using)... then, in your application, you are using some socket, or some way to call an external program (probaly a cURL.exe in the local machine, again lots of important details being guessed).... to skip on unnecessary tasks, please confirm that the request is getting to the server. Finally, what does `curl --data "x=4&y=2" http://localhost:8080/CurlServer/curl/curltutorial/sumPost` yelds? Exactly as its is here. What does the console say? – Bonatti Sep 23 '15 at 16:41
  • @Bonatti it yelds zero and I already states in the question, i am using apache 8, and yes the request is going to the server because i put a lot of system.out.println and they are working – Marco Dinatsoli Sep 23 '15 at 17:00
  • @MarcoDinatsoli And the console says? – Bonatti Sep 23 '15 at 17:02
  • oh, the console says that x = 0 and y = 0, – Marco Dinatsoli Sep 23 '15 at 17:03
  • @MarcoDinatsoli To be sure, the sumPost, when requested, what is building the json itself? shouldnt the java input be something like `{"x":4,"y":2}` What does: `curl -X POST http://localhost:8080/CurlServer/curl/curltutorial/sumPost -d '{"x":4,"y":2}` yelds? – Bonatti Sep 23 '15 at 17:17
0

Have you tried calling it like this:

curl -XPOST "http://localhost:8080/CurlServer/curl/curltutorial/sumPost?x=5&y=3" 

?

Yuriy Dubyna
  • 82
  • 1
  • 6