Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How request works in Play Framework 2?

I've got to say I'm a little confused about how to handle request parameter using the new Play Framework 2. The data comes from different origins regarding how the request is made. So far, here's the possibilities :

1 - If you do a simple GET :

ctx().request().queryString()

2 - If you do a POST using an HTML Form :

The form :

<form method="post" action="/">
    <input type="hidden" name="foo" value="bar" />
    <input type="hidden" name="t" value="1" />
    <input type="hidden" name="bool" value="true" />
    <input type="submit" name="submit" value="Submit" />
</form>

The method :

public static Result test() {
    ctx().request().queryString();             // {} ; As expected
    ctx().request().body();                    // contains data
    ctx().request().body().asFormUrlEncoded(); // contains data
    ctx().request().body().asJson();           // empty
    return ok();
}

This seems normal.

Now if I add @BodyParser.Of(BodyParser.Json.class) (suppose I accept both Ajax POST and normal POST for fallback in Non-JS case) :

@BodyParser.Of(BodyParser.Json.class)
public static Result test() {
    ctx().request().queryString();             // {} ; as Expected
    ctx().request().body();                    // contains data
    ctx().request().body().asFormUrlEncoded(); // empty : Shouldn't this contains data since I posted them via a simple form ?!
    ctx().request().body().asJson();           // empty
    return ok();
}

And then, the hell hapened : How can I get the values of a simple form if none of them are filled (asJson, asFormUrlEncoded, etc) ?!

3 - If you do a POST via AJAX :

// Code in JS used :
$.ajax({
    'url': '/',
    'dataType': 'json',
    'type': 'POST',
    'data': {'foo': 'bar', 't': 1, 'bool': true}
});

Result :

public static Result test() {
    ctx().request().queryString();             // {}
    ctx().request().body();                    // contains data
    ctx().request().body().asFormUrlEncoded(); // contains data
    ctx().request().body().asJson();           // empty
    return ok();
}

With the @BodyParser.Of(BodyParser.Json.class) :

@BodyParser.Of(BodyParser.Json.class)
public static Result test() {
    ctx().request().queryString();             // {}
    ctx().request().body();                    // contains data
    ctx().request().body().asFormUrlEncoded(); // empty
    ctx().request().body().asJson();           // empty : Shouldn't this contains data since I espect JSON ?!
    return ok();
}

Here the inconsistencies is the asJson() method that should return the data since, according to the doc

Note: This way, a 400 HTTP response will be automatically returned for non JSON requests. (http://www.playframework.org/documentation/2.0/JavaJsonRequests)

What I'd like to know is what is the best decorator+method for a POST that would accept a simple post from HTML or an Ajax Request with POST?

like image 624
Cyril N. Avatar asked Apr 25 '12 08:04

Cyril N.


People also ask

How Play framework works?

The Play framework is a web framework for the JVM that breaks away from the Servlet Specification. Play embraces a fully reactive programming model through the use of futures for asynchronous programming, work stealing for maximizing available threads, and Akka for distribution of work.

Is Play RESTful by default?

A RESTful ArchitecturePlay's architecture is RESTful by default. At its core, Play is based on the Model-View-Controller pattern.

What is action in play framework?

What is an Action? Most of the requests received by a Play application are handled by an action. An action is basically a Java method that processes the request parameters, and produces a result to be sent to the client. public Result index(Http. Request request) { return ok("Got request " + request + "!"

Why use Play framework?

Play Framework makes it easy to build web applications with Java & Scala. Play is based on a lightweight, stateless, web-friendly architecture. Built on Akka, Play provides predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications.


1 Answers

I would recommend to use the Form classes provided by PlayFramework. The Form will bind its values to the provided request data.

There are two different Form implementations:

  1. DynamicForm: POST data is available through Map accessors methods
  2. Form: the generic form of Form will map the POST data to an instance of an entity class [more information]

    The form also provides some usefull features like automatic type conversion, validation, error reporting and so on.

a simple example with a dynamic form:

ajax request:

$.post("@routes.Application.movetodo()", 
    { "id": 123, "destination": destination }, function(data)
        {
           // do something when request was successfull
        });

Routes file:

GET     /                           controllers.Application.index()
POST    /movetodo                   controllers.Application.movetodo()

Controller implementation:

public static Result movetodo()
{
    DynamicForm data = form().bindFromRequest(); // will read each parameter from post and provide their values through map accessor methods
    // accessing a not defined parameter will result in null
    String id = data.get("id");
    String destination = data.get("destination");

    return ok();
}
like image 111
Johann Sonntagbauer Avatar answered Oct 26 '22 02:10

Johann Sonntagbauer