Play中的bindFromRequest问题! 框架2.3
我正在尝试使用Play的自动绑定function,但没有成功。 我正在用Java 4.4 Luna开发Java。
这是我的表格:
Create a new user
这是我的class级“用户”:
@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 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会因为自动构建function而导致问题。 注意:这是要走的路,但我没有使用activator命令清理项目,正如用户Dmitri建议的那样。 此外,只需在Eclipse中不启用自动构建function,您只需执行一次。
我已经尝试过多次重启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() { @Override public User parse(String arg0, Locale arg1) throws ParseException { User u = new Model.Finder(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之间存在一些不兼容性! 框架的编译器……
我一直在努力解决完全相同的问题:bindFromRequest为“name”字段返回了空值。 这个Play for Java介绍video中的人做的完全相同:youtube.com/watch?v = bLrmnjPQsZc。 但仍然没有运气。 我一直在使用JDK 1.8开发Windows 7。 IDE:Eclipse 4.4.0。 我通过cygwin运行激活器。
这就是我解决问题的方法:
- 在Eclipse中:项目 – >自动构建 – >关闭
- 在cygwin中:./ activator clean; ./activator编译; ./activator run;
在此之后,bindFromRequest正确绑定名称并将其放入数据库。
为您的数据模型创建getter / setter。 它解决了我的问题。
在您的代码中,您有:
Users u = Form.form(Users.class).bindFromRequest().get();
试试这个:
Users user = new Users(); Form u = Form.form(Users.class).fill(user).bindFromRequest();
编辑:
问题可能是你正在使用的输入类型。 尝试生成这样的表单:
@form(routes.Backend.createUser()) { @inputText(userForm("first_name"))
@inputText(userForm("first_name"))
@inputText(userForm("email"))
@inputText(userForm("pin"))
@inputText(userForm("status"))
@checkbox(userForm("is_guest"))
}
然后在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 userForm = Form.form(Users.class).bindFromRequest(); Users user = userForm .get(); user.save(); } }
绑定和数据库之间绝对没有链接。 不要按照@blackbishop的建议告诉您将模型的所有字段更改为String。 这是一个非常糟糕的主意,如果有不同的类型,有一个原因……
此外,Ebean(假设您正在使用它)或JPA根据您的Java属性类型生成数据库列类型。 为什么要在varchar列中存储0或1?
遵循以下规则:
- 为模型使用单数名称(
User
而不是Users
) - 始终对您的属性使用驼峰大小写,没有下划线(firstName而不是first_name,lastName而不是last_name …)
- 绑定后获取值之前检查错误
这应该给你这个:
public static Result createUser() { Form form = Form.form(User.class).bindFromRequest(); if (form.hasErrors()) { // Do what you have to do (ie : redirect to the form with a flash message) } User u = form.get(); u.save(); return redirect(routes.Backend.allUsers()); }
顺便说一句,在测试行中, user_id
是正确生成的,因为您没有validation规则,这些数据来自数据库,而不是表单。
我通过添加Setters和Getters解决了这个问题。 如果您有实体/模型类,则应添加setter和getter。 如果你有FormData类,也为它添加setter和getter。
所以当你打电话
Form formData = Form.form(YourFormData.class).bindFromRequest(); YourFormData formData = formData.get();
您的formData现在将设置所有值。 希望这可以帮助!
我知道这篇文章有一个接受的答案,但想发表我对这个问题的经验。
我遇到了同样的问题并执行了上面答案中提到的所有步骤,即自动构建Eclipse,然后通过激活器进行清理和编译。 但是,这不起作用。 我尝试了许多不同的方法,甚至从头创建了一个项目,而没有创建任何Eclipse依赖项。 不过,它没有用。
然后,我查看了我的模型并决定尝试更改我的属性名称的情况,然后瞧! 有效!
这是我的模型看起来像以前:
public class Test { public String FirstName; public String LastName;}
现在,我改变它看起来像这样:
public class Test { public String firstName; public String lastName;}
只是想指出这一点,因为它不明显,我来自.Net