目前,我正在尝试在弹簧形式多选中绑定模型,但出现错误。

产品型号如下:

 @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...


子类别模型如下:

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


运行代码时,在“选择框”中得到“类别”,在“多个选择框”中得到“子类别”。但是,当我单击“提交”按钮时,SubCategory的值为空。

java - 如何在Spring Form Multiple Select中绑定(bind)模型数据-LMLPHP

当我尝试通过添加itemvalue和itemid绑定如下所示的子类别时,出现错误

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


错误:


  org.springframework.beans.NotReadablePropertyException:无效
  Bean类[java.lang.Integer]的属性'subCategoryId':Bean
  属性“ subCategoryId”不可读或具有无效的获取器
  方法:getter的返回类型是否与的参数类型匹配
  二传手?
  
  我已经在我的subCategoryId和subCategoryName属性
  SubCategory Model类。


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

非常感谢。

最佳答案

更换

<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属性通常填充有item对象的集合或数组。如果已指定,则itemValue和itemLabel只是引用那些item对象的bean属性;否则,item对象本身将被字符串化。或者,您可以指定项目映射,在这种情况下,映射键将解释为选项值,并且映射值对应于选项标签。如果恰好同时指定了itemValue和/或itemLabel,则item value属性将应用于地图键,item label属性将应用于地图值。


请特别参考粗体文本。

从您的代码示例中,似乎模型属性'subCategoryName'是Integer键和String值的映射。因此,对于作为地图的模型属性,根据上述Spring文档中的引文,地图关键字会自动解释为选项值,而相应的地图值会自动解释为相应的选项标签。这就是为什么您无需指定itemValueitemLabel的原因。但是您仍在指定。因此,按照上述引号中黑体字的第二行,在itemValue中指定的任何内容都将解释为映射键的bean属性-在您的情况下为integer。因此,这就是Spring尝试在Integer类中查找“ subCategoryId”字段及其获取器的原因,因此失败并引发错误。

09-05 05:15