Java SpringMVC表单:选项标签没有连接到我的对象Id?

Java SpringMVC表单:选项标签没有连接到我的对象Id?,java,spring,forms,spring-mvc,jstl,Java,Spring,Forms,Spring Mvc,Jstl,我试图在列表框中显示我的命令对象集合字段。在所述集合的内部是一个字段、id和名称。我想使用id作为html选项值,使用名称作为选项文本。见下面的代码 <form:select id="customCollection" path="customCollection" size="10"> <form:options items="${command.customCollection}" itemValue="id" itemLabel="name"/> </

我试图在列表框中显示我的命令对象集合字段。在所述集合的内部是一个字段、id和名称。我想使用id作为html选项值,使用名称作为选项文本。见下面的代码

<form:select id="customCollection" path="customCollection" size="10">
    <form:options items="${command.customCollection}" itemValue="id" itemLabel="name"/>
</form:select>
当我从initBinder方法中删除这段代码时,行值被正确地插入到表单中,但我需要一个customEditor将所述值转换为数据库对象

这是我对活页夹的新尝试

binder.registerCustomEditor(Collection.class, "customCollection",
        new CustomCollectionEditor(Collection.class) {

    @Override
    protected Object convertElement(Object element) {
        Integer id = null;

        if (element instanceof Integer) {
            id = (Integer) element;
        }
        return id != null ? dao.find(Custom.class, id) : null;
    }
});
但是,这会导致与上一个绑定器相同的行为,并使值不显示。你知道我做错了什么吗

编辑2: 正如我前面提到的,如果我注释掉我的自定义绑定器,那么自定义对象确实为表单的视图部分正确加载了它的id和名称,但是当我试图保存它时,它永远不会绑定回父对象。所以我真的认为问题在于我的活页夹


我已经在convertElement方法中放置了调试语句。一切看起来都应该工作,dao正确地从数据库中提取对象。唯一让我感到可疑的行为是,convertElement方法对每个自定义项调用了两次。

我认为不正确的一点是,command.customCollection用于填充表单的select输入的可能值,并绑定到用户使用该select选择的最终值输入这没有道理,至少对我来说。。。例如,如果我有一个用于选择地址的美国州的表单select,我会用有效州的集合填充该select,但我会将select的值绑定到用户最终选择的一个州

尝试以下操作:在命令对象的上下文之外创建customCollection对象。换句话说,现在customCollection是command对象的属性;相反,将该对象从命令对象中拉出,并使其成为自己的页面属性。在SpringMVC模型中,将用作下拉列表等数据源的东西通常称为参考数据;在SimpleFormController中,此数据将填充到适当命名的方法中。这分离了两个不同的概念-参考数据中select live的可能值,以及用户在绑定到表单和/或select输入的命令对象中选择的最终值

因此,假设这是在SimpleFormController中,请尝试添加或适当修改referenceData,如下所示:

然后将您的更改为:

<form:select id="customCollection" path="command" size="10">
  <form:options items="${customCollection}" itemValue="id" itemLabel="name"/>
</form:select>

这有意义吗?

我将尝试提供一个工作示例,它可能有助于调试您遇到的问题:

<form:form commandName="client" method="post" action="${edit_client}">
    <form:select path="country">
        <form:options items="${requestScope.countries}" itemValue="id" itemLabel="name"/>
    </form:select>
</form:form>
我在控制器的initBinder方法中使用自定义属性编辑器。我将省略实现,因为它使用通用实现

binder.registerCustomEditor(Country.class, "country", editorServiceFactory.getPropertyEditor(Country.class, CustomPropertyEditor.class));
以下是从控制器的referenceData方法调用此方法的参考数据:

public Map<String, List<?>> getDemographicReferenceData() {
    Map<String, List<?>> referenceData = new HashMap<String, List<?>>();
    referenceData.put("countries", countryDAO.findAll());
    return referenceData;
}

我使用的是Spring2.5,这是一个问题,一旦我了解出了什么问题,我就不知道它是如何工作的

我使用CustomCollectionEditor的方式完全错误。根据Marten Deinum在

正如我在另一个线程中所述,CustomCollectionEditor将创建集合列表,Set?。因此,它将使用所需类型的元素填充所需集合

但是,它并不打算将单个元素转换为值。它设计用于集合,而不是单个角色实例。您希望1个PropertyEditor为您执行2项任务

因此,它为每个元素创建了一个唯一的集合,当它试图生成HTML时,这些元素最终在Spring代码中被置空

这就是我最后要做的

binder.registerCustomEditor(Custom.class,
        new PropertyEditorSupport() {

            @Override
            public void setAsText(String text) {
                Custom custom = dao.find(Custom.class,
                        Integer.parseInt(text));
                setValue(Custom);
            }
        });

我不知道为什么我以前的CustomCollectionEditor将名称作为值使用。

Spring标记看起来是正确的。检查集合中对象的.equals方法。equals方法基于id。有什么限制?form:options?equals方法将确定何时显示所选属性,该属性通常基于对象的id。由于id未显示,可能存在某种相关性。这只是需要验证的东西。我并不是说它可以解决您的问题。@BacMan,这很奇怪,因为列表框中的所有项目都已选中,这表明表单控制器可以识别它们都与command对象关联。您能否调试Spring源代码以查看对您的对象所做的操作?e、 g.曾经有过这样一种情况,我实在无法理解为什么Spring标签行为不端。我将Spring源代码安装到Eclipse中,并在调试时进行设置。大约一个小时后,我发现我的应用程序上下文是从错误的文件加载的,并且标记所做的事情是正确的,只是指向了wr
昂山素人。我看到您使用了NetBeans,所以我不确定您是如何做到这一点的,但您可以尝试一下吗?现在就尝试一下,这很有意义。只是想让你知道我在做什么;我有两个状态列表框,借用你的例子,一个框选择了状态,另一个框没有选择状态。您可以将状态移动到“选定状态”框中以选择它们,反之亦然。只是尝试了一下,在引用数据中引用customCollection时,我得到的行为与从命令对象内部提取数据完全相同。因此,所有可能状态的列表都是引用数据,并应填充在referenceData方法中;所选状态的列表将在命令对象中结束。将其简化为最简单的示例:允许多个选择的表单选择输入…-选项来自用户可能选择的参考池,用户所做的最终选择随表单提交一起返回,并由Spring MVC用于填充您的命令对象。您使用的Spring版本是什么?只是想消除差异…2.5不确定子版本,我使用的是Netbeans 6.7的标准jar。我将在周一讨论这个问题,但有一个简单的问题,您的活页夹是否会影响放置在表单上的数据,我认为在提交数据后,不会在下进行绑定。该绑定自定义编辑器可能是我的问题,也可能是我的equals方法。它可以确定是否选中该选项,并在提交时再次将id转换回对象。让我重新表述一下。equals方法确定是否选择了该选项。要将id转换为对象,请使用自定义编辑器。
<form:form commandName="client" method="post" action="${edit_client}">
    <form:select path="country">
        <form:options items="${requestScope.countries}" itemValue="id" itemLabel="name"/>
    </form:select>
</form:form>
public class Country {

    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(final Object anObject) {
        if (anObject == null) {
            return false;
        } else if (this == anObject) {
            return true;
        } else if (anObject instanceof Country) {
            final Country aCountry = (Country) anObject;
            Integer aCountryId = aCountry.getId();
            if (aCountryId != null) {
                return aCountry.getId().equals(id);
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        return id;
    }
}
binder.registerCustomEditor(Country.class, "country", editorServiceFactory.getPropertyEditor(Country.class, CustomPropertyEditor.class));
public Map<String, List<?>> getDemographicReferenceData() {
    Map<String, List<?>> referenceData = new HashMap<String, List<?>>();
    referenceData.put("countries", countryDAO.findAll());
    return referenceData;
}
binder.registerCustomEditor(Custom.class,
        new PropertyEditorSupport() {

            @Override
            public void setAsText(String text) {
                Custom custom = dao.find(Custom.class,
                        Integer.parseInt(text));
                setValue(Custom);
            }
        });