我在Spring中遇到了表单数据绑定问题。
给定的是具有以下结构的对象:
- SiteContent
|-List<Panel> boxList
panel元素如下所示:
- Panel
|- Collection<AbstractPanelElement> panelElements
AbstractPanelElements
的集合是关键点,因为AbstractPanelElements
可能是Divider
,Address
或Icon
。
如果我提交包含这些类型的几个元素的表单,我会收到以下错误:
org.springframework.beans.InvalidPropertyException:
Invalid property 'boxList[0].panelElements[0]' of bean class [com.panel.SiteContent]:
Illegal attempt to get property 'panelElements' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException:
Invalid property 'boxList[0].panelElements' of bean class [com.panel.SiteContent]:
Could not instantiate property type [com.panel.AbstractPanelElement] to auto-grow nested property path: java.lang.InstantiationException
经过研究,我发现我们可以在Controller中设置以下(InitBinder):
@InitBinder
public void initBinder(WebDataBinder binder){
binder.setAutoGrowNestedPaths(false);
}
但是这并没有解决问题,因此我认为Spring不能实例化一个抽象类。
现在我的问题是,我可以解决这个问题还是没办法?
答案 0 :(得分:1)
您需要提供自己的Binding方法,然后创建正确的子类型。 Spring不会知道应该为哪个元素实例化哪个子类型。
一个例子是这样的:
@ModelAttribute("item")
public Item getItem(final HttpServletRequest request){
String type = request.getParameter("type");
if (type!=null){
if (type.equals(TYPE1.class.getSimpleName())){
return new TYPE1();
}
if (type.equals(TYPE2.class.getSimpleName())){
return new TYPE2();
}
throw new RuntimeException("OH NOES! Type unknown!");
}
return null;
}
您也可以修改它以处理列表项。 在我的脑海中,我知道你可以实现PropertyEditors从字符串表示到类。但我现在的研究时间有限。