Reputation: 1
So I am trying to build a simple REST API and wanted to try out spark but for some reason I can't seem to extract any parameters.
Here is my endpoint for testing this:
post("/hello", (req, res) -> {
String str = req.attribute(":username"); //TODO THIS IS ALWAYS NULL!!!!!!!
System.out.println(str);
System.out.println("BODY IS WORKING:");
System.out.println(req.body().toString());
return "PANNKAKA";
});
Now if I try to make a request at http://localhost:4567/hello with the body { "username": "bla" }, the str variable is just null. But if I call on the body method on req, req.body().toString(); it does indeed get the body: { "username": "bla" } printed to the console. So the body is coming through.
This is the result in the console window:
null
BODY IS WORKING:
[
{
"username": "bla"
}
]
So how do you extract the parameter from the request's body? I have tried lots of different formatting on the param name but it just doesn't work. Been sitting with this for hours now!
I have looked at the documentation and I believe I do the correct thing: http://sparkjava.com/documentation.html
Upvotes: 0
Views: 4241
Reputation: 1652
as Laercio said, if you want to get the value of this line
String str = req.attribute(":username"); //TODO THIS IS ALWAYS NULL!!!!!!!
you should declare the same var as part of your URI
post("/hello/:username" ...) ...
but if you are trying to send a JSON as Content-Type: application/json
you won't get the params by that way, this only works if your send the value as Content-Type: application/x-www-form-urlencoded
and then your can use req.params("username")
this last is the way that ordinary HTML form send the data
Java doesn't handle very well JSON by default, you need to do some tricks to do that, or even better use Gson
If you don't want to use Gson, so you need to read the body line per line and handle by your own that data sent by application/json to get the data.
Upvotes: 0
Reputation: 1359
You should have declared your route like the following, with the parameter :username as part of the route name:
post("/hello/:username", (req, res) -> {
String str = req.attribute(":username"); //TODO THIS IS ALWAYS NULL!!!!!!!
System.out.println(str);
System.out.println("BODY IS WORKING:");
System.out.println(req.body().toString());
return "PANNKAKA";
});
or, if what you wanted is to deal with query parameters, just take a look at this answer.
Upvotes: 0
Reputation: 2616
I guess there are few ways to do this. Also, you didn't mention it by I'm assuming you send your data formatted as JSON.
I do that using an ObjectMapper (using this package com.fasterxml.jackson.databind.ObjectMapper
) and a PayLoad class.
I create a simple class used as the PayLoad. It contains just fields and their getters and setters. for each value you send in the JSON you'll create the corresponding field, with exactly the same name In your case you'll have a field called username
), and then the object mapper maps the JSON that you sent from the client to this class pattern. Example:
public class UserPayload {
private long id;
private String username;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
Then I parse the request body into this payload using the object mapper:
class SomeClass {
...
private static Object postUser(Request req, Response res) throws JSONException {
ObjectMapper mapper = new ObjectMapper();
UserPayload pl = null;
try {
pl = mapper.readValue(req.body(), UserPayload.class); // <------
} catch (JsonMappingException e1) {
...
} catch (Exception e2) {
...
}
System.out.println(pl.getUsername() + " " + pl.getId());
...
}
}
And of course register your route:
post("/hello", SomeClass::postUser);
Hope it helps. If someone uses a simpler way, I'll be happy to hear.
Upvotes: 1