简体   繁体   中英

PlayFramework (2.5.x) doesn't bind data from form returning Ojbect with null fields

The problem is to bind data from form (or from Map of parameters) to actual Form object. I have added some println just for testing purposes. Here is code for Controller class.

package controllers;

import java.util.List;

import javax.inject.Inject;

import models.Product;
import play.data.Form;
import play.data.FormFactory;
import play.mvc.Controller;
import play.mvc.Result;

import views.html.products.list;
import views.html.products.details;

public class Products extends Controller {

@Inject
public Products(FormFactory formFactory) {
    productForm =  formFactory.form(Product.class);
  }

private static Form<Product> productForm;

public  Result list(){
    List<Product> products = Product.findAll();
    return ok(list.render(products));
}
public  Result newProduct(){
    return ok(details.render(productForm));
}
public  Result save(){
    Form<Product> filledForm=productForm.fill(new Product("0000","0000","0000"));
    Form<Product> boundForm=productForm.bindFromRequest();
    final Product product =(Product) boundForm.get();
    System.out.println(">>Bound ean form data: "+boundForm.field("ean").value()+"->Product from bound form: "+boundForm.get());
    System.out.println(">>Filled ean form data: "+filledForm.field("ean").value()+"->Product from filled form: "+filledForm.get());
    //product.save();
    flash("success",String.format("Successfully added product %s", product));
    return redirect(routes.Products.list());
}

}

Here for the purpose of simplicity class Product is just of three public fields:

package models;


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", ean, name);
    }


}

And here is Play template( without main wrapper template that take care of <head> <body> stuff)

@(productForm: Form[Product])
@import helper._

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

}

Everything rides nice and smooth except that I get Product object with null fields, but field(fieldName).value() or data() return correct data. Looks like Form behaves as DynamicForm. Strange things starting to happen when I use bind(Map<String,String>) instead of bindFromRequest() - same result both. And resul from console is (i have used testEAN filling the form "ean" field)

    >>Bound ean form data: testEAN->Product from bound form: null - null
    >>Filled ean form data: null->Product from filled form: 0000 - 0000

Need to add property accessors/mutators ( getXXX/setXXX ) in Product class . That is crucial point

You have to provide the type of the form

Form<Product> boundForm = factoryForm.form(Product.class).bindFromRequest();
Product product = boundForm.get();

If you do not provide the type of the object you are biding how play will infer the fields and properties?!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM