【问题标题】:Java Play: bindFromRequest() not workingJava Play:bindFromRequest() 不起作用
【发布时间】:2014-07-25 17:08:30
【问题描述】:

我正在尝试使用 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()

接下来,我在controllers.Application里面有个动作addPerson,就是

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,每个都显示person 对象中name 属性的空值,以及尝试使用form.get("name") 检索时的空值。

我已经尝试过我认为解决此问题的最佳方法,但我并没有真正在网上看到太多关于此问题的信息。这似乎太基本了,不可能成为 Play 框架的问题。

我在这里做错了什么?

请注意,我使用的是 Mac,并且正在使用 mySQL 来存储数据。

【问题讨论】:

  • 谁能回答这个问题?我相信这是一个非常简单的情况,显然这里有一些非常错误的地方。如果像这样的简单案例无法工作,没有明显的原因/警告,我怀疑在任何现实世界场景中都依赖 Play。
  • 你让它工作了吗?怎么样?
  • @Gevorg 恐怕在这一点上我放弃了尝试将 Java 与 Play 框架一起使用。我借此机会深入研究了 Scala,并发现了更多关于常见障碍的文档和在线讨论。从那以后,我部署了我的第一个基于 Play-Scala 的 API。 ;-)

标签: java html scala playframework forms http-post


【解决方案1】:

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

原因: 当您将 Eclipse 项目首选项设置为 Build automatically 时,问题似乎出现了。这会弄乱 play 生成的类,并在更改时用 eclipse 生成的类覆盖它。

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

让我知道这是否有效,很多人都面临同样的问题。这可能应该是文档本身中的提示Reference

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      首先,您需要覆盖模型中的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>
      }
      

      【讨论】:

        【解决方案4】:

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

        我真的希望介绍视频包含这个作为 Eclipse 用户在 Play 框架上的安全点。

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

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

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

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

            尝试简单

            person.name
            

            而不是

            form().get("name")
            

            获取属性值。

            一切都应该没问题。否则你会在 person.save() 调用中得到 NullPointerException

            【讨论】:

              【解决方案7】:

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

              所以当你打电话时

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

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

              【讨论】:

                猜你喜欢
                • 2014-11-23
                • 2017-08-26
                • 2016-08-28
                • 2012-07-21
                • 2015-12-08
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多