绑定Spring MVC中的列表映射

我不确定这是否是一个复杂的问题,但作为一个初学者,这对我来说似乎有点复杂。 我有一个对象,我需要在UI上显示一些值,让用户选择其中的一些,我需要在用户点击提交按钮时将数据发送回另一个控制器。这是我的数据对象的结构

public class PrsData{ private Map<String, List> prsCDData; } public class PrsCDData{ private Map<String, Collection> configuredDesignData; } public ConfiguredDesignData{ // simple fields } 

我在显示视图之前在模型中设置了对象

 model.addAttribute("prsData", productData.getPrData()); 

在表格中,我有以下设置

 

这就是我在AddProductToCartController

 public String addToCart(@RequestParam("productCodePost") final String code, @ModelAttribute("prsData") final PrsData prsData, final Model model, @RequestParam(value = "qty", required = false, defaultValue = "1") final long qty) 

在提交表格后,我将收到例外情况

 org.springframework.beans.NullValueInNestedPathException: Invalid property 'prsCDData[Forced][0]' of bean class [com.product.data.PrsData]: Cannot access indexed value of property referenced in indexed property path 'prsCDData[Forced][0]': returned null 

它似乎试图访问此控制器上的值,而我正在尝试向该控制器发送值并尝试使用所选值创建相同的对象

任何人都能告诉我我做错了什么以及我需要照顾什么

编辑

我做了一些更多的研究,并且发现Spring不支持自定义对象的自动填充列表/地图,并根据我试图改变实现的答案

 public class PrsData{ private Map<String, List> prsCDData; // lazy init public PrsData() { this.prsCDData = MapUtils.lazyMap(new HashMap<String, List>(), FactoryUtils.instantiateFactory(PrsCDData.class)); } } public class PrsCDData{ private Map<String, Collection> configuredDesignData; public PrsCDData() { this.configuredDesignData = MapUtils.lazyMap(new HashMap<String, List>(), FactoryUtils.instantiateFactory(ConfiguredDesignData.class)); } } 

但我得到以下例外

 org.springframework.beans.InvalidPropertyException: Invalid property 'prsCDData[Forced][0]' of bean class [com.data.PrsData]: Property referenced in indexed property path 'prsCDData[Forced][0]' is neither an array nor a List nor a Set nor a Map; returned value was [com.data.PrsCDData@6043a24d] 

我不确定我做错了什么,似乎我的JSTL表达不正确

说明:如果在您的控制器中您拥有@ModelAttribute("user") User user ,并且您加载了包含的相应页面,则会实例化一个空用户。

它的所有属性都为null,如果是List或Map,则为空。 此外,它的空列表/映射已经使用自动增长实现进行了实例化。 这是什么意思 ? 假设我们有一个空的自动增长List coconuts 。 如果我执行coconuts.get(someIndex).setDiameter(50) ,它将工作而不是抛出exception,因为列表自动增长并实例化给定索引的椰子。
由于这种自动增长function,提交带有以下输入的表单将像魅力一样:

  

现在回到你的问题: Spring MVC自动增长对一组对象很有效,每个对象都包含一个map / list( 参见这篇文章 )。 但是,鉴于您的exception,看起来Spring不会自动增长自动增长列表/映射包含的可能对象。 在Map> prsCDDataList只是一个没有自动增长的空列表,因此导致您的exception。

所以解决方案必须使用某种Apache Common的LazyList或Spring的AutoPopulatingList 。
您必须实现自己的自动增长映射,该映射为给定索引实例化LazyList / AutoPopulatingList。 从头开始或使用某种Apache Common的LazyMap / MapUtils.lazyMap实现(到目前为止,我还没有找到LazyMap的Spring等价物)。

解决方案示例,使用Apache Commons Collections:

 public class PrsData { private Map> prsCDData; public PrsData() { this.prsCDData = MapUtils.lazyMap(new HashMap>(), new Factory() { public Object create() { return LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(PrsCDData.class)); } }); } }