Java Play:bindFromRequest()不起作用

时间:2014-07-25 17:08:30

标签: java html scala playframework html-form-post

我正在尝试使用Java Play,而且我遇到了直接的障碍。情况非常简单,设置简单。

我有一个名为Person的模型类,非常简单,看起来像这样;

package models.models;

import play.db.ebean.Model;

import javax.persistence.Entity;
import javax.persistence.Id;

/**
 * Created by asheshambasta on 25/07/14.
 */
@Entity
public class Person extends Model {

    @Id
    public Integer id;

    public String name;
}

我的路线定义为;

POST    /person                     controllers.Application.addPerson()

接下来,我在addPerson内部有一个动作controllers.Application,即

public static Result addPerson() {
    Person person = form(Person.class).bindFromRequest().get();
    person.save();
    Logger.debug(person.toString());
    Logger.debug(form().get("name"));
    return redirect(controllers.routes.Application.index());
}

index.scala.html看起来像是:

@(message: String)

@main("Welcome to Play") {
        <form action="@routes.Application.addPerson()" method="post">
            <input type="text" name="name" />
            <button>Add person</button>
        </form>
}

我还检查了浏览器调试工具,并看到name表单元素正确发布到服务器。

发生的事情很奇怪:在动作中似乎没有任何表单参数可见。正如您所看到的,我有两个Logger.debug,其中每个都显示name对象中person属性的null,以及尝试时使用form.get("name")检索。

我已经尝试过我能看到的最好的方法来解决这个问题但我在网上看不到这个问题。这似乎太基础了,不能成为Play框架的问题。

我在这里做错了什么?

作为一个说明,我在Mac上,我使用mySQL来存储数据。

7 个答案:

答案 0 :(得分:6)

在尝试使用Java时,我也遇到了同样的问题。

原因:当您将Eclipse项目首选项设置为Build automatically时,似乎会出现问题。这会混淆play所产生的类,并将其改为eclipse在更改时生成的类。

解决方案: Disable the 'build automatically'来自项目设置和终端,执行play clean从Play创建课程。

如果有效,请告诉我,很多人都面临同样的问题。这应该是文档本身的一个提示Reference

答案 1 :(得分:3)

您是否尝试为属性创建setter / getter?可能是某些代码生成的问题:(。尝试将属性更改为私有并创建访问器方法

答案 2 :(得分:2)

首先,您需要覆盖模型中的toString()方法(同时添加查找器并将其直接移至models包!):

package models;

import play.db.ebean.Model;
import javax.persistence.Entity;
import javax.persistence.Id;


@Entity
public class Person extends Model {

    @Id
    public Integer id;

    public static Finder<Integer, Person> find = new Finder<>(Integer.class, Person.class);

    public String name;

    public String toString() {
        return this.name;
    }
}

第二,在访问其字段之前,您需要bindFromRequest() form()

public static Result addPerson() {
    Person person = form(Person.class).bindFromRequest().get();
    person.save();
    Logger.debug(person.toString());
    Logger.debug(form().bindFromRequest().get("name"));
    return redirect(controllers.routes.Application.index());
}

最后,您可以显示现有人员名单,例如:

public static Result index() {
    List<Person> persons = Person.find.all();
    return ok(index.render(persons));
}

视图:

@(persons: List[Person])

@main("Welcome to Play") {
    <form action="@routes.Application.addPerson()" method="post">
        <input type="text" name="name" />
        <button>Add person</button>
    </form>
}

Already added:
@for(person <- persons){
    <div>@person</div>
}

答案 3 :(得分:1)

我在2天后面临同样的问题,发现这个问题非常特定于Eclipse。我刚刚禁用了“自动构建”并执行了“构建清理”(在构建清理期间未选中“清理后构建”复选框)并找到要存储在数据库中的条目。

我真的希望介绍视频将此作为Play框架上eclipse用户的安全点。

答案 4 :(得分:1)

使用playframework 2.3.7添加我最近遇到的类似JSON请求问题。在我的情况下,它只是通过简单地将playframework升级到版本2.3.8(在失去2次无限调试之后)来修复。

如果您想重现错误,可以尝试下载并运行Play-Authenticate's sample app并使用playframework 2.3.7。在doLogin()请求中,您将看到bindFromRequest对JSON请求失败。

答案 5 :(得分:0)

第一个Logger调用打印 toString()的默认实现,

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

因为您没有在类Person中覆盖它。

尝试简单

person.name

而不是

form().get("name")

可以访问属性的值。

一切都应该没问题。否则,您将在 person.save()调用中获得 NullPointerException

答案 6 :(得分:0)

我通过添加Setter和Getters来解决这个问题。 如果您有实体/模型类,则应添加setter和getter。 如果你有FormData类,也可以为它添加setter和getter。

所以当你打电话

Form<YourFormData> formData = Form.form(YourFormData.class).bindFromRequest(); 
YourFormData formData = formData.get(); 

您的formData现在将设置所有值。 希望这可以帮助!