Issue
I have two models :
public class Size {
private String name;
// getter and setter
}
public class Product {
private int id;
private String designation;
private Float price;
private List<Size> availableSizes;
// Getter and setters
}
I have defined Sizes in my servlet, and now I nead to create products with the availables sizes.
What I do in my index Controller:
ModelAndView render = new ModelAndView("admin/index");
render.addObject("products", productFactory.getProducts());
render.addObject("sizes", sizeFactory.getSizes());
render.addObject("command", p);
return render;
I've a list of products, and my list of sizes.
In my index view, I do:
<form:form method="post" action="/ecommerce/admin/products" class="form-horizontal">
<form:input path="id" />
<form:input path="designation" />
<form:input path="price" />
<form:select path="availableSizes" items="${sizes}"/>
<input type="submit" value="Ajouter le produit" class="btn" />
</form:form>
Then, in new product controller, I do :
// To fix: Sizes not saved !
@RequestMapping(value = "/products", method = RequestMethod.POST)
public ModelAndView newProduct(@ModelAttribute("Product") Product product,
BindingResult result) {
productFactory.add(product);
return buildIndexRender(null, null, product);
}
The problem is that I keet the posted product, but not the corresponding sizes.
Is there a way to keep selected sizes in the form int the controler, or directly in the model?
Thanks.
Solution
It's a very common problem.
To set a List<Size>
in Product instance from the post data, that is a string colon separated list with selected sizes, all you need to do is tell the framework how to convert a size String
to a Size
instance. The most common approach is registering a PropertyEditor
on WebDataBinder
class SizePropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
Size size = stringToSize(text); // write this code
setValue(size);
}
}
and register the property editor in Controller using @InitBinder
annotation
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Size.class, new SizePropertyEditor());
}
For a more generic approach see ConversionService.
Answered By - Jose Luis Martin
Answer Checked By - Terry (JavaFixing Volunteer)