3

我一直在阅读“Play for Java”一书,这本书非常出色。我对 Java 还很陌生,但我一直在关注这些示例,我有点卡在第 3 章。代码可以在这里找到:Play for Java on GitHub

问题是当我执行 boundform.get() 时,表单的实际属性似乎并没有将其放入“产品”对象中。我已经在 Eclipse 的调试器中暂停了它,并且所有值都在该行正确设置,Form<Product> boundForm = productForm.bindFromRequest();但是当我到达product.save().

我的控制器、模型、路由和表单如下所示。如果需要任何其他信息,请告诉我。

Products.java(控制器)

package controllers;

import models.Product;
import play.data.Form;
import play.mvc.Result;
import play.mvc.Controller;
import views.html.products.*;

import java.util.List;

public class Products extends Controller {

    private static final Form<Product> productForm = Form.form(Product.class);

    public static Result list() {
        List<Product> products = Product.findAll();
        return ok(list.render(products));
    }

    public static Result newProduct() {
        return ok(details.render(productForm));
    }

    public static Result details(String ean) {
        return TODO;
    }

    public static Result save() {
        Form<Product> boundForm = productForm.bindFromRequest();
        Product product = boundForm.get();
        product.save();
        return ok(String.format("Saved product %s", product));
    }

}

Product.java(模型)

package models;

import java.util.ArrayList;
import java.util.List;

public class Product {

    public String ean;
    public String name;
    public String description;

    public Product() {

    }

    public Product(String ean, String name, String description) {
        this.ean = ean;
        this.name = name;
        this.description = description;
    }

    public String toString() {
        return String.format("%s - %s", this.ean, this.name);
    }

    private static List<Product> products;

    static {
        products = new ArrayList<Product>();
        products.add(new Product("1111111111111", "Paperclips 1",
                "Paperclips description 1"));
        products.add(new Product("2222222222222", "Paperclips 2",
                "Paperclips description "));
        products.add(new Product("3333333333333", "Paperclips 3",
                "Paperclips description 3"));
        products.add(new Product("4444444444444", "Paperclips 4",
                "Paperclips description 4"));
        products.add(new Product("5555555555555", "Paperclips 5",
                "Paperclips description 5"));
    }

    public static List<Product> findAll() {
        return new ArrayList<Product>(products);
    }

    public static Product findByEan(String ean) {
        for (Product candidate : products) {
            if (candidate.ean.equals(ean)) {
                return candidate;
            }
        }
        return null;
    }

    public static List<Product> findByName(String term) {
        final List<Product> results = new ArrayList<Product>();
        for (Product candidate : products) {
            if (candidate.name.toLowerCase().contains(term.toLowerCase())) {
                results.add(candidate);
            }
        }
        return results;
    }

    public static boolean remove(Product product) {
        return products.remove(product);
    }

    public void save() {
        products.remove(findByEan(this.ean));
        products.add(this);
    }
}

路线

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

# Home page
GET     /                           controllers.Application.index()
GET     /products/                  controllers.Products.list()
GET     /products/new               controllers.Products.newProduct()
GET     /products/:ean              controllers.Products.details(ean: String)
POST    /products/                  controllers.Products.save()

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path="/public", file)

details.scala.html

@(productForm: Form[Product])

@import helper._

@import helper.twitterBootstrap._

@main("Product form") {
    <h1>Product form</h1>
    @helper.form(action = routes.Products.save()) {
        <fieldset>
            <legend>Product (@productForm("name").valueOr("New"))</legend>
            @helper.inputText(productForm("ean"), '_label -> "EAN")
            @helper.inputText(productForm("name"),'_label -> "Name")
            @helper.textarea(productForm("description"), '_label -> "Description")
        </fieldset>
        <input type="submit" class="btn btn-primary" value="Save">
        <a class="btn" href="@routes.Application.index()">Cancel</a>
    }
}

我敢肯定,这是一件非常明显的事情。非常感谢!

4

2 回答 2

3

请参阅文档处理绑定失败部分。调用.get()aForm并不安全,因为如果存在验证错误,它将返回null。首选的方法是首先通过检查错误hasErrors(),然后从那里处理它。

if (boundform.hasErrors()) {
    /* There are errors somewhere in the form, 
    * return it to the view and display them there, 
    * or do whatever else you need to handle the error.
    */
    return badRequest(...);
} else {
    // A valid `Product`, proceed as normal.
    Product product = boundform.get();

    return ok(....);
}
于 2014-06-23T14:54:27.493 回答
2

SBT 缓存问题。我跑了activator clean,一切正常。

我开始从 GitHub 存储库中粘贴整个文件,看看是否可以缩小范围。这导致了一组新的错误,这些错误让我想到了这个 StackOverflow 问题,该问题在线程中有 SBT 缓存建议。

我很欣赏这个错误方法 LimbSoup 的建议和链接。无论如何,肯定会调查这些,并且我相信我将来可能会不止一次地参考您的答案!

非常感谢,大家。

于 2014-06-24T01:50:20.540 回答