Java - 在传递" this"时,在对象属性中获取空值。

时间:2014-06-23 13:58:26

标签: java eclipse scala playframework-2.3

我一直在阅读“Play for Java”一书,这本书绝对精彩。我仍然是Java的新手,但我一直在关注这些示例,我对第3章感到困惑。代码可以在这里找到:Play for Java on GitHub

问题在于,当我执行boundform.get()时,表单的实际属性似乎没有进入“product”对象。我在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(model)

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>
    }
}

我确信这是非常明显的事情。非常感谢你!

2 个答案:

答案 0 :(得分:3)

请参阅documentation处理绑定失败部分。在.get()上调用Form并不安全,因为如果存在验证错误,则会返回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(....);
}

答案 1 :(得分:2)

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

我开始粘贴GitHub仓库中的整个文件,看看我是否可以缩小范围。这导致了一组新的错误,这些错误使我this StackOverflow question在线程中有了SBT缓存建议。

我很欣赏有关错误方法LimbSoup的建议和链接。肯定会不顾一切地考虑那些,并且我相信我将来可能不止一次地引用你的答案!

非常感谢,所有人。