Java SpringMVC表单:选项标签没有连接到我的对象Id?
我试图在列表框中显示我的命令对象集合字段。在所述集合的内部是一个字段、id和名称。我想使用id作为html选项值,使用名称作为选项文本。见下面的代码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"/> </
<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);
}
});