如何在Spring Form Multiple Select中绑定模型数据

时间:2017-01-10 17:25:35

标签: java spring jsp spring-mvc

目前我正在尝试以弹簧形式绑定模​​型多选,但我收到错误。

产品型号如下:

 @Entity
    public class Product implements Serializable {

        private static final long serialVersionUID = -3532377236419382983L;

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private int productId;

        @OneToMany(mappedBy = "product", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
        @JsonIgnore
        private List<CartItem> cartItemList;

        @ManyToOne
        @JoinColumn(name = "categoryId")
        @JsonIgnore
        private Category category;

        @ManyToMany
        @JsonIgnore
        @JoinTable(name="PRODUCT_SUBCATEGORY", 
                    joinColumns={@JoinColumn(name="productId")}, 
                    inverseJoinColumns={@JoinColumn(name="subCategoryId")})
        private List<SubCategory> subCategoryList;


        public List<SubCategory> getSubCategoryList() {
            return subCategoryList;
        }

        public void setSubCategoryList(List<SubCategory> subCategoryList) {
            this.subCategoryList = subCategoryList;
        }
Getter Setter...

SubCategory模型如下:

@Entity
public class SubCategory implements Serializable {


    private static final long serialVersionUID = 7750738516036520962L;

    @Id
    @GeneratedValue
    private int subCategoryId;

    @NotEmpty(message = "The subcategory name must not be empty")
    @Size(min = 3, max = 20, message = "Minimum 3 to 20 characters allowed")
    private String subCategoryName;

    @ManyToOne
    @JoinColumn(name="categoryId")
    private Category category;
Getter and Setter...

控制器类如下:

@Controller
@RequestMapping("/admin")
public class AdminProduct {

    private Path path;

    @Autowired
    private ProductService productService;

    @Autowired
    private SubCategoryService subCategoryService;

    @Autowired
    private CategoryService categoryService;

    @RequestMapping("/product/addProduct")
    public String addProduct(Model model){
        Product product = new Product();
        model.addAttribute("product", product);

        return "addProduct";
    }
    @ModelAttribute("subCategoryName")
    public Map<Integer, String> populateSubCategoryTypes() {
        Map<Integer, String> subCategoryNameMap = new HashMap<Integer, String>();
        List<SubCategory> subCategoryList = this.subCategoryService.getAllSubCategroy();
        for (SubCategory subCategory : subCategoryList) {
            subCategoryNameMap.put(subCategory.getSubCategoryId(),subCategory.getSubCategoryName());
        }
        return sortByValue(subCategoryNameMap);
    }

    public <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(
                map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                return (o1.getValue()).compareTo(o2.getValue());
            }
        });

        Map<K, V> result = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

addProduct.jsp如下:

 <form:form action="${pageContext.request.contextPath}/admin/product/addProduct"
                   method="post" commandName="product" enctype="multipart/form-data">
            <div class="form-group">
            <label for="category.categoryName">Category Name*</label>
            <form:select id="categoryName" path="category.categoryId" class="form-Control">
                <form:options items="${categoryName}" />
            </form:select>
            </div>

            <div class="form-group">
            <label for="subCategoryList">SubCategory Name*</label>
            <form:select items="${subCategoryName}"  multiple="true" path="subCategoryList" class="form-Control" />
            </div>
        <input type="submit" value="submit" class="btn btn-default">
        <a href="<c:url value="/admin/productInventory" />" class="btn btn-default">Cancel</a>

    </form:form>

当我运行我的代码时,我在Select Box中选择Category,在Multiple Select Box中获得SubCategory。但是当我点击提交按钮时,我的SubCategory为空。

enter image description here

当我尝试通过添加itemvalue和itemid来绑定下面的子类别时,我收到错误

<form:select items="${subCategoryName}" itemValue="subCategoryId" itemLabel="subCategoryName"  multiple="true" path="subCategoryList" class="form-Control" />

错误:

  

org.springframework.beans.NotReadablePropertyException:无效   bean类的属性'subCategoryId'[java.lang.Integer]:Bean   属性“subCategoryId”不可读或具有无效的getter   method:getter的返回类型是否与参数类型匹配   二传手?

     

我已经拥有了subCategoryId和subCategoryName属性   SubCategory模型类。

请帮助我如何绑定数据以获取选择的子类别值。

非常感谢你。

1 个答案:

答案 0 :(得分:2)

替换

<form:select items="${subCategoryName}" itemValue="subCategoryId" itemLabel="subCategoryName" multiple="true" path="subCategoryList" class="form-Control" />

<form:select items="${subCategoryName}" multiple="true" path="subCategoryList" class="form-Control" />

请注意,我建议的唯一更改是从itemValue标记中删除属性itemLabelform:select

<强>原因

Spring docs开始,我引用了以下内容:

  

items属性通常使用项目对象的集合或数组填充。如果指定,itemValue和itemLabel只是引用那些项目对象的bean属性;否则,项目对象本身将被字符串化。或者,您可以指定项目的地图,在这种情况下,地图键被解释为选项值,地图值对应于选项标签。如果恰好也指定了itemValue和/或itemLabel,则item value属性将应用于地图键,而item label属性将应用于地图值。

特别参考粗体文字。

从您的代码示例中,似乎模型属性&#39; subCategoryName&#39;是Integer键和String值的地图。因此,对于作为地图的模型属性,根据上面Spring文档的引用,地图键自动解释为选项值,相应的地图值自动解释为相应的选项标签。这就是您不需要指定itemValueitemLabel的原因。但是你仍在指明这一点。因此,根据上面引用的粗体文本中的第二行,您在itemValue中指定的任何内容都被解释为映射键的bean属性 - 在您的情况下为integer。这就是为什么Spring试图找到&#39; subCategoryId&#34;字段及其在Integer类中的getter因此失败并抛出错误。