Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with bindFromRequest in Play! Framework 2.3

I'm trying to use the automatic binding feature of Play, without success. I'm developing in Java, on Eclipse 4.4 Luna.

Here is my form :

<h2>Create a new user</h2>
<form action="@routes.Backend.createUser()" method="post">
    First Name
    <input type="text" name="firstName" />
    Last Name
    <input type="text" name="lastName" />
    E-mail
    <input type="email" name="email" />
    PIN
    <input type="number" name="pin" />
    Status
    <input type="text" name="status" />
    Is guest?
    <input type="checkbox" name="isGuest" />

    <input type="submit" value="Create user" />
</form>

Here is my class "Users":

@Entity
public class Users extends Model {

// Database columns
@Id
public int userId;

public String firstName;
public String lastName;
public String email;
public int pin;
public String status;
public boolean isGuest;

}

And here is my controller:

public class Backend extends Controller {

  public static Result createUser() {
    Form<Users> form = Form.form(Users.class).bindFromRequest();
    if (form.hasErrors()) {
        // doSomething()
    } else {
        Users u = form.get();
        u.save();
    }

    // TESTING
    // Checking the content of the request
    DynamicForm requestData = Form.form().bindFromRequest();
    String firstName = requestData.get("firstName");
    String lastName = requestData.get("lastName");
    // Printing the content works, I am able to see the correct values
    System.out.println(firstName); // Bob
    System.out.println(lastName); // Smith
    // This somehow doesn't work...
    System.out.println(u.firstName); // NULL
    System.out.println(u.lastName); // NULL
    System.out.println(u.userId); // Correctly generated
    // END OF TESTING

    return redirect(routes.Backend.allUsers());
  }
}

I wonder why the automatic binding of values doesn't work. I have made sure that the fields name in my form correspond to the attributes names in the class, and this should be enough for the form binding to work, right?

I am using Eclipse Luna, and I turned off automatic project build (I do it manually from the console). I know that sometimes Eclipse can cause issues because of that auto-build feature. Note: This was the way to go, but I didn't clean the project using the activator command, as user Dmitri suggested. Also, you only have to do this once, as long as you don't turn on the automatic build feature in Eclipse.

I have tried restarting Eclipse and the application several times, without success...

EDIT: I tried using only String attributes for my Users class, since the requestData.get(String s) method returns a String. But still no success...

EDIT 2: I'm going to bind the values manually... If anyone have an idea, please post :)

EDIT 3: I've updated my code to follow the rules mentioned in the answer below

EDIT 4: I can't get autobinding working only when using my Postgresql 9.3 database. When I use in-memory database, everything works smoothly. Also, since there was no JDBC driver for Java 8 and postgresql 9.3, I'm using an older version of the driver (actually the driver is on PGSQL's website, but I couldn't get it working with Play). I will have to check what happens with another DB, then I'll report back here!

EDIT 5: I tried to create my custom data binder like this:

        Formatters.register(User.class, new Formatters.SimpleFormatter<User>() {
        @Override
        public User parse(String arg0, Locale arg1) throws ParseException {
            User u = new Model.Finder<Integer, User>(Integer.class, User.class).byId(Integer.parseInt(arg0));
            return u;
        }
        @Override
        public String print(User arg0, Locale arg1) {
            return "User : " + arg0.firstName;
        }
    });

... but it didn't work!

EDIT 6: User Dmitri has found a working solution: you have to compile the project outside of Eclipse. It seems that there is some incompatibilities between Eclipse's compilator and Play! Framework's compilator...

like image 665
Danish Ashfaq Avatar asked Aug 18 '14 14:08

Danish Ashfaq


People also ask

Is Play framework still used?

Play is rock-solid and used by hundreds of thousands of Java and Scala developers every month. Play is still extremely relevant to today's application and web development and has a passionate and very capable community around it ensuring that it has many good years left.

Is play a good framework?

Play is a direct competitor to Spring framework and designed to develop and deploy web applications more efficiently and also provides better MVC framework. In terms of getting a web application up and running quickly, play is the best. Spring and Spring MVC cannot compete with play framework individually.

Is Play framework backend?

Play comes with two configurable server backends, which handle the low level work of processing HTTP requests and responses to and from TCP/IP packets. Starting in 2.6. x, the default server backend is the Akka HTTP server backend, based on the Akka-HTTP server.

What is form in play framework?

Play's form handling approach is based around the concept of binding data. When data comes in from a POST request, Play will look for formatted values and bind them to a Form object. From there, Play can use the bound form to value a case class with data, call custom validations, and so on.


1 Answers

I have been struggling with exactly the same problem: bindFromRequest returned nulls for "name" field. I did exactly the same what a guy in this Play for Java introduction video did: youtube.com/watch?v=bLrmnjPQsZc . But still no luck. I've been working on Windows 7 with JDK 1.8. IDE: Eclipse 4.4.0. And I run activator through cygwin.

This is what solved the problem for me:

  1. In Eclipse: Project -> Build Automatically - > turn off
  2. In cygwin: ./activator clean; ./activator compile; ./activator run;

After this, bindFromRequest binds name correctly and puts it into the database.

like image 175
Dmitri Lihhatsov Avatar answered Nov 15 '22 17:11

Dmitri Lihhatsov