Reputation: 23587
Thread is in continuation of sending-data-back-to-controller-spring-mvc
I am working on a product detail page where I need to show user some options and user will select few of them and on the submit button product should get added to the basket. My intentions are to transfer that Data object to my Cart Controller so that I can use those values and since the object contains dynamic values so its not possible to define a pre decided fields object. This is my data object
public class PrsData {
private Map<String, List<PrsCDData>> prsCDData;
public PrsData(){
this.prsCDData = MapUtils.lazyMap(new HashMap<String, List<PrsCDData>>(),
FactoryUtils.instantiateFactory(PrsCDData.class));
}
}
public class PrsCDData {
private Map<String, List<ConfiguredDesignData>> configuredDesignData;
// same lazy map initialization
}
In my product detail page controller, I am setting the values as:
model.addAttribute("prsData", productData.getPrsData());
and on my product detail page JSP I have this in my form:
<form:form method="post" commandName="prsData" action="${addProductToCartAction}" >
<form:hidden path="prsCDData[''${prsCDDataMap.key}'']
[${status.index}].configuredDesignData['${configuredDesignDataMap.key}']
[${configuredDesignDataStatus.index}].code" />
</form:form>
But when I click on submit button I am getting the following exception
org.springframework.beans.InvalidPropertyException:
Invalid property 'prsCDData['Forced'][0]' of bean class [com.product.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.product.data.PrsCDData@6164f07e]
I am not sure where I am doing wrong as on the product detail page these hidden fields are getting binded correctly and have even values assigned to them but when form is getting submitted I am facing this issue.
Upvotes: 1
Views: 1745
Reputation: 4239
the LazyMap factory has to return a LazyList.
the given factory FactoryUtils.instantiateFactory(PrsCDData.class) creates a new PrsCDData object rather than a List of PrsCDData.
prsCDData['Forced'] -> if exists then return it else create instance of PrsCDData.class
should be
prsCDData['Forced'] -> if exists then return it else create instance of LazyList<PrsCDData>
use LazyList since you immediately want to access index '0' what leads to a ArrayIndexOutOfBoundsExecption otherwise
EDIT: Simple example
public class Test {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws UnsupportedEncodingException {
Map<String, List<SimpleBean>> map = MapUtils.lazyMap(new HashMap<String,List<Object>>(),new Factory() {
public Object create() {
return LazyList.decorate(new ArrayList<SimpleBean>(), FactoryUtils.instantiateFactory(SimpleBean.class));
}
});
System.out.println(map.get("test").get(0));
}
public static class SimpleBean {
private String name;
}
}
Upvotes: 1