我正在尝试使用Play的自动绑定功能,但没有成功。我正在用Java 4.4 Luna开发Java。
这是我的表格:
<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>
这是我的班级“用户”:
@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;
}
这是我的控制器:
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());
}
}
我想知道为什么值的自动绑定不起作用。我确保我的表单中的字段名称对应于类中的属性名称,这应该足以使表单绑定起作用,对吗?
我正在使用Eclipse Luna,我关闭了自动项目构建(我从控制台手动完成)。我知道有时Eclipse会因为自动构建功能而导致问题。 注意:这是要走的路,但是我没有像使用Dmitri建议的那样使用activator命令清理项目。此外,只需要在Eclipse中不启用自动构建功能,就只需执行一次。
我已经尝试多次重启Eclipse和应用程序,但没有成功......
修改 我尝试只为我的Users类使用String属性,因为requestData.get(String s)方法返回一个String。但仍然没有成功......
编辑2: 我要手动绑定值...如果有人有想法,请发帖:)
编辑3: 我已更新我的代码,以遵循以下答案中提到的规则
编辑4: 我只能在使用Postgresql 9.3数据库时才能进行自动绑定。当我使用内存数据库时,一切都很顺利。此外,由于没有用于Java 8和postgresql 9.3的JDBC驱动程序,我使用的是较旧版本的驱动程序(实际上驱动程序在PGSQL的网站上,但我无法使用Play)。我将不得不检查另一个数据库会发生什么,然后我会在这里报告!
编辑5: 我尝试创建我的自定义数据绑定器:
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;
}
});
......但它不起作用!
编辑6: 用户Dmitri找到了一个可行的解决方案:您必须在Eclipse之外编译项目。似乎Eclipse的编译器和Play之间存在一些不兼容性!框架的编译器......
答案 0 :(得分:12)
我一直在努力解决完全相同的问题:bindFromRequest为&#34; name&#34;返回了null。领域。我做了与Play for Java介绍视频中的一个人完全相同的事:youtube.com/watch?v = bLrmnjPQsZc。但仍然没有运气。 我一直在使用JDK 1.8在Windows 7上工作。 IDE:Eclipse 4.4.0。我通过cygwin运行激活器。
这就解决了我的问题:
在此之后,bindFromRequest正确绑定名称并将其放入数据库。
答案 1 :(得分:5)
为您的数据模型创建getter / setter。它解决了我的问题。
答案 2 :(得分:2)
在您的代码中,您有:
Users u = Form.form(Users.class).bindFromRequest().get();
请尝试使用此功能:
Users user = new Users();
Form <Users> u = Form.form(Users.class).fill(user).bindFromRequest();
编辑:
问题可能是你正在使用的输入类型。尝试生成这样的表单:
@form(routes.Backend.createUser()) {
<label>First Name:</label> @inputText(userForm("first_name")) <br />
<label>Last Name:</label> @inputText(userForm("first_name")) <br />
<label>Email:</label> @inputText(userForm("email")) <br />
<label>Pin:</label> @inputText(userForm("pin")) <br />
<label>Status:</label> @inputText(userForm("status")) <br />
<label>Is Guest:</label> @checkbox(userForm("is_guest")) <br />
<input type="submit" value="Create user" />
}
然后在User Entity
中:尝试将所有列类型更改为String
@Entity
public class Users extends Model {
// Database columns
@Id
public int user_id;
public String first_name;
public String last_name;
public String email;
public String pin;
public String status;
public String is_guest;
}
在您的控制器中:
public class Backend extends Controller {
public static Result createUser() {
Form <Users> userForm = Form.form(Users.class).bindFromRequest();
Users user = userForm .get();
user.save();
}
}
答案 3 :(得分:1)
绑定和数据库之间绝对没有链接。不要按照@blackbishop的建议告诉您将模型的所有字段更改为String。这是一个非常糟糕的主意,如果有不同的类型,有一个原因......
此外,Ebean(假设您正在使用它)或JPA根据您的Java属性类型生成数据库列类型。为什么要在varchar列中存储0或1?
遵循以下规则:
User
代替Users
)那应该给你这个:
public static Result createUser() {
Form<User> form = Form.form(User.class).bindFromRequest();
if (form.hasErrors()) {
// Do what you have to do (i.e. : redirect to the form with a flash message)
}
User u = form.get();
u.save();
return redirect(routes.Backend.allUsers());
}
顺便说一句,在您的测试行中,user_id
是正确生成的,因为您没有验证规则,而且这些数据来自数据库,而不是表单。
答案 4 :(得分:1)
我通过添加Setter和Getters来解决这个问题。 如果您有实体/模型类,则应添加setter和getter。 如果你有FormData类,也可以为它添加setter和getter。
所以当你打电话
Form<YourFormData> formData = Form.form(YourFormData.class).bindFromRequest();
YourFormData formData = formData.get();
您的formData现在将设置所有值。 希望这可以帮助!
答案 5 :(得分:0)
我知道这篇文章有一个公认的答案,但想发表我对这个问题的经验。
我遇到了同样的问题并执行了上面答案中提到的所有步骤,即Eclipse自动构建,然后通过激活器进行清理和编译。但是,这不起作用。我尝试了许多不同的方法,甚至从头创建了一个项目,而没有创建任何Eclipse依赖项。不过,它没有用。
然后,我查看了我的模型并决定尝试更改我的属性名称的情况,然后瞧!它奏效了!
以下是我的模型之前的样子:
public class Test {
public String FirstName;
public String LastName;}
现在,我改变它看起来像这样:
public class Test {
public String firstName;
public String lastName;}
只是想指出这一点,因为它不明显,我来自.Net