Feras Odeh
Feras Odeh

Reputation: 9296

Grails send request as JSON and parse it in controller

I want to send a request as JSON and in my controller I want to parse this JSON and get the parameters I want. for example this is the request:

{"param1":"val1"}

I want to parse this request and get "param1" value. I used request.JSON but still I got null. Is there any other way to solve this?

Thanks,

Upvotes: 6

Views: 17258

Answers (3)

tavi
tavi

Reputation: 680

You can use one of the following to test your stuff (both options could be re-used as automated tests eventually - unit and integration):

write a unit test for you controller like (no need to start the server):

void testConsume() {
     request.json = '{param1: "val1"}'
 controller.consume()       
 assert response.text == "val1"
}

and let's say your controller.consume() does something like:

def consume() {
    render request.JSON.param1
}

Or you can use for example the Jersey Client to do a call against your controller, deployed this time:

public void testRequest() {
    // init the client
    ClientConfig config = new DefaultClientConfig();
    Client client = Client.create(config);

    // create a resource
WebResource service = client.resource(UriBuilder.fromUri("your request url").build());
    // set content type and do a POST, which will accept a text/plain response as well
    service.type(MediaType.APPLICATION_JSON).accept(MediaType.TEXT_PLAIN).put(Foo.class, foo);
}

, where foo is a Foo like this:

@XmlRootElement
public class Foo {
    @XmlElement(name = "param1")
    String param1;

    public Foo(String val){param1 = val;}      
}

Here are some more examples on how to use the Jersey client for various REST requests: https://github.com/tavibolog/TodaySoftMag/blob/master/src/test/java/com/todaysoftmag/examples/rest/BookServiceTest.java

Upvotes: 4

Brian Henry
Brian Henry

Reputation: 3171

In the controller method, check request.format. It should specify json. I'm guessing it won't here, but it may give you clues as to how your payload is being interpreted.

In your Config.groovy file, I would set the following values:

grails.mime.file.extensions = false
grails.mime.use.accept.header = false

In that same file, check your grails.mime.types. make sure it includes json: ['application/json', 'text/json'], which it probably will, but put it above */*. These entries are evaluated in order (this was true in pre 2.1 versions, havent' verified it is now, but what the heck). In conjunction with that, as aiolos mentioned, set your content-type header to one of the above mime-types.

Finally, test with curl, per Tomasz Kalkosiński, or, to use RESTClient for FF, click on "Headers" in the very top of the client page (there are 4 clickable items at the top-left; headers is one. From a fresh RESTClient, you may have to choose "Custom Header". I can't recall)

Upvotes: 0

Tomasz Kalkosiński
Tomasz Kalkosiński

Reputation: 3723

Set it in your UrlMappings like this:

static mappings = {
    "/rest/myAction" (controller: "myController", action: "myAction", parseRequest: true)
}

Search for parseRequest in latest Grails guide.

Then validate if it works correctly with curl:

curl --data '{"param1":"value1"}' --header "Content-Type: application/json" http://yourhost:8080/rest/myAction

Upvotes: 3

Related Questions