【问题标题】:Spring MVC binding nested objectsSpring MVC 绑定嵌套对象
【发布时间】:2014-05-08 00:05:42
【问题描述】:

我有以下类的一个实例,我想在其中编辑它,然后将其保存回后端。

public class NestedClass {
    List<InnerClass> inners = new LinkedList<InnerClass>();

    //getter and setter

    public class InnerClass {
        private String innerField;

        //getter and setter
   }
}

编辑:编辑示例代码以满足@Slava Semushin 的建议。

当我实例化类并将其传递给模型时,我可以使用以下 jsp sn-p 读取值:

<form:input path="inners[0].innerField" /><br/>
<form:input path="inners[1].innerField" /><br/>

但是当我把它传回去时,我得到了以下异常:

Invalid property 'inners[0]' of bean class [com.sodacrm.webapp.forms.NestedClass]: Illegal attempt to get property 'inners' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'inners' of bean class [com.sodacrm.webapp.forms.NestedClass]: Could not instantiate property type [com.sodacrm.webapp.forms.NestedClass$InnerClass] to auto-grow nested property path: java.lang.InstantiationException: com.sodacrm.webapp.forms.NestedClass$InnerClass
org.springframework.beans.InvalidPropertyException: Invalid property 'inners[0]' of bean class [com.sodacrm.webapp.forms.NestedClass]: Illegal attempt to get property 'inners' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'inners' of bean class [com.sodacrm.webapp.forms.NestedClass]: Could not instantiate property type [com.sodacrm.webapp.forms.NestedClass$InnerClass] to auto-grow nested property path: java.lang.InstantiationException: com.sodacrm.webapp.forms.NestedClass$InnerClass

我使用的真实类是 3 级深,我不想将内部类放在单独的文件中,因为它们强烈属于它们的外部类...

【问题讨论】:

  • 任何原因InnerClass 未定义为static
  • 这可能是内部类不是静态的,或者缺少 getter/setter,或者 autogrow 没有被设置。话虽如此,使用传输对象确实没有什么可耻的。进行 DTO 通常更安全,责任更单一,尽管 DRY 不那么干燥。
  • 我也遇到了同样的问题,你是怎么解决的?

标签: java spring inner-classes spring-form


【解决方案1】:

你如何为inners 成员定义getter?检查它是否总是返回有效列表:

List<InnerClass> inners = new LinkedList<InnerClass>();

public List<InnerClass> getInners() {
    if (inners == null) {
        inners = new LinkedList<InnerClass>();
    }
    return inners;
}

【讨论】:

  • 你说得对,我忘了设置列表。但是当我设置它时,会发生同样的异常......
  • 仅供参考 - 在谈论数据绑定时,spring 将创建您的集合的实例并自动增长其组件。不需要初始化集合。检查DataBinder#setAutoGrowNestedPaths(默认启用)。 docs.spring.io/spring/docs/3.1.x/javadoc-api/org/…
【解决方案2】:

原因是内部类。 Spring 仅在给定内部类类型的情况下实例化内部类,此类没有对 NestedClass 实例的引用,因此实例化失败(因为 InnerClass 的实例只能存在于实例的上下文中NestedClass)

不幸的是,修复方法是将 InnerClass 移出 NestedClass 的范围或将其声明为静态内部类。此外,您不需要实例化内部列表,它会自动实例化为ArrayList

这可能值得一张Jira 票,尽管它似乎是对 Spring 框架的一个很好的增强。

【讨论】:

  • 如果模型对象被正确初始化并且autoGrowNestedPaths被禁用,绑定将起作用。然而,以这种方式做动态表单是不可能的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
相关资源
最近更新 更多