2014-12-22 75 views
0

的模型我创建了一个表单,它有2个字段(产品名称和价格)以及类别对象(产品类别)的下拉列表。 我不知道如何使这项工作,当我有一个类别对象设置在产品对象。Spring MVC表单 - 参考对象

产品:

public class Product { 
    private String name; 
    private Category category; 
    private int price; 

    public Product() { 
    } 

    public Product(String name, Category category, int price) { 
     this.name = name; 
     this.category = category; 
     this.price = price; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public Category getCategory() { 
     return category; 
    } 

    public void setCategory(Category category) { 
     this.category = category; 
    } 

    public int getPrice() { 
     return price; 
    } 

    public void setPrice(int price) { 
     this.price = price; 
    } 

} 

产品控制器:

@ModelAttribute("categoryList") 
    public List<Category> categoryList() { 
      return categoryService.getCategories(); 
    } 

    @RequestMapping("/products/add") 
    public ModelAndView addProductForm() { 
     ModelAndView mv = new ModelAndView("addProduct"); 

     mv.addObject("product", new Product()); 
     return mv; 
    } 
    @RequestMapping(value = "/products/add/process", method = RequestMethod.POST) 
    public ModelAndView addProduct(@ModelAttribute("product") Product product) { 
     ModelAndView mv = new ModelAndView("products"); 
     System.out.println("added " + product.getName() + " " + product.getPrice()); 
     return mv; 
    } 

形式:

<form class="form-horizontal" action="#" 
     th:action="@{/products/add/process}" th:object="${product}" 
     method="post"> 
     <fieldset> 

      <!-- Form Name --> 
      <legend>Add product</legend> 

      <!-- Text input--> 
      <div class="form-group"> 
       <label class="col-md-4 control-label" for="textinput">Product 
        name</label> 
       <div class="col-md-4"> 
        <input id="textinput" name="textinput" placeholder="Product name" 
         class="form-control input-md" required="" type="text" 
         th:field="*{name}"></input> 
       </div> 
      </div> 

      <!-- Select Basic --> 
      <div class="form-group"> 
       <label class="col-md-4 control-label" for="selectbasic">Category</label> 
       <div class="col-md-4"> 
        <select th:field="*{category}"> 
         <option th:each="cat : ${categoryList}" th:value="${cat.getId()}" 
          th:text="${cat.getName()}"></option> 
        </select> 
       </div> 
      </div> 

      <!-- Text input--> 
      <div class="form-group"> 
       <label class="col-md-4 control-label" for="textinput">Price</label> 
       <div class="col-md-4"> 
        <input id="textinput" name="textinput" placeholder="" 
         class="form-control input-md" required="" type="text" 
         th:field="*{price}"></input> 
       </div> 
      </div> 

      <!-- Button --> 
      <div class="form-group"> 
       <label class="col-md-4 control-label" for="singlebutton"></label> 
       <div class="col-md-4"> 
        <button id="singlebutton" name="singlebutton" 
         class="btn btn-success">Add product</button> 
       </div> 
      </div> 
     </fieldset> 
    </form> 

附加从评论
当我SUBM信息它它(见addProduct方法 - 这是一个表单处理程序)我得到:java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.example.shop.Category] for property 'category': no matching editors or conversion strategy found]。我简直无法将字符串从下拉菜单转换为对象

+0

所以我明白的问题正确:该类别的下拉是空的,因为你永远不会设置它。你如何获得填充值并返回到表单? – Ascalonian

+0

@Ascalonian我在下拉菜单中显示它们,我使用ModelAttribute注释将它们作为列表传递(我使用categoryService获取它)。 – tomdavies

+0

然后我不明白“如何使这项工作”的意思,因为你说下拉显示值。你能更详细地描述你想要完成的事情吗? – Ascalonian

回答

1

问题是,Spring没有从StringCategory的内置转换功能。它知道它需要Category才能使用ProductsetCategory(Category category)方法,但无法将您从发布的下拉菜单中获得的String转换为一个。因此,您需要成为一名亲爱的人,告诉它如何进行转换并定义一个转换器,以帮助其他人,请参阅Spring docs了解更多信息。

最简单的方法是使用转换器SPI:

package com.example.shop.converter; 

final class StringToCategoryConverter implements Converter<String, Category> { 
    public Category convert(String source) { 
    Category category; 

    // Put your conversion logic here 

    return category; 
    } 
} 

在你的情况,我想你想使用:CategoryService.getCategory(int id)或类似的方法。

然后,你需要春天配置实际使用的转换器,下面是如何做到这一点的XML例子:

<mvc:annotation-driven conversion-service="conversionService" /> 

<bean id="conversionService" 
     class="org.springframework.context.support.ConversionServiceFactoryBean"> 
    <property name="converters"> 
     <list> 
      <bean class="com.example.shop.converter.StringToCategoryConverter" /> 
     </list> 
    </property> 
</bean> 
+0

非常感谢!你是对的 - 我添加了一个转换器:)。 更重要的是 - 如果你有“注解驱动的”启用后,您还需要这种方式注册您的转换器: tomdavies

+0

好一点,编辑的答案,包括它适用于任何人后来到这里。 – t0mppa