Spring绑定抽象对象

时间:2015-03-23 13:14:09

标签: java spring spring-mvc spring-boot

我在Spring中遇到了表单数据绑定问题。

给定的是具有以下结构的对象:

- SiteContent
|-List<Panel> boxList

panel元素如下所示:

- Panel
|- Collection<AbstractPanelElement> panelElements

AbstractPanelElements的集合是关键点,因为AbstractPanelElements可能是DividerAddressIcon

如果我提交包含这些类型的几个元素的表单,我会收到以下错误:

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不能实例化一个抽象类。

现在我的问题是,我可以解决这个问题还是没办法?

1 个答案:

答案 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从字符串表示到类。但我现在的研究时间有限。

这可能对您有所帮助: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-beans-conversion-customeditor-registration