【问题标题】:Spring binding abstract ObjectSpring绑定抽象对象
【发布时间】:2015-03-23 13:14:09
【问题描述】:

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

Given 是一个具有以下结构的对象:

- SiteContent
|-List<Panel> boxList

面板元素如下所示:

- 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无法实例化抽象类。

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

【问题讨论】:

  • 这个异常是什么时候发生的?导致当 boxList.panelElements 为 null 并且您尝试向其中添加元素时,似乎会出现 NullValueInNestedPathException。
  • 表单提交后会抛出异常。我调试它并认识到如果 spring 尝试实例化 panelElement (AbstractPanelElement)

标签: java spring spring-mvc spring-boot


【解决方案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; 
}

您也可以修改它来处理列表项。 在我的脑海中,我知道您可以实现一些 PropertyEditor 从字符串表示到类。但我现在研究的时间有限。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 2014-11-06
    • 2016-09-13
    • 2013-01-17
    • 2014-05-08
    • 1970-01-01
    • 2012-04-25
    相关资源
    最近更新 更多