目前,我正在尝试在弹簧形式多选中绑定模型,但出现错误。
产品型号如下:
@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的值为空。
当我尝试通过添加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
标记中删除属性itemLabel
和form:select
。
原因:
在Spring docs中,我引用了以下内容:
items属性通常填充有item对象的集合或数组。如果已指定,则itemValue和itemLabel只是引用那些item对象的bean属性;否则,item对象本身将被字符串化。或者,您可以指定项目映射,在这种情况下,映射键将解释为选项值,并且映射值对应于选项标签。如果恰好同时指定了itemValue和/或itemLabel,则item value属性将应用于地图键,item label属性将应用于地图值。
请特别参考粗体文本。
从您的代码示例中,似乎模型属性'subCategoryName'是Integer
键和String
值的映射。因此,对于作为地图的模型属性,根据上述Spring文档中的引文,地图关键字会自动解释为选项值,而相应的地图值会自动解释为相应的选项标签。这就是为什么您无需指定itemValue
和itemLabel
的原因。但是您仍在指定。因此,按照上述引号中黑体字的第二行,在itemValue
中指定的任何内容都将解释为映射键的bean属性-在您的情况下为integer
。因此,这就是Spring尝试在Integer
类中查找“ subCategoryId”字段及其获取器的原因,因此失败并引发错误。