hujja
hujja

Reputation: 1

Extract param data from request with spark

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

Answers (3)

Juorder Gonzalez
Juorder Gonzalez

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

Laercio Metzner
Laercio Metzner

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

SHG
SHG

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

Related Questions