将Spring MVC表单数据绑定的字符串转换为自定义对象?

将Spring MVC表单数据绑定的字符串转换为自定义对象?,spring,data-binding,forms,spring-mvc,persistence,Spring,Data Binding,Forms,Spring Mvc,Persistence,我使用SpringMVC的SimpleFormController和SpringMVC的表单JTL来创建一个表单来编辑通用对象 在我的表单上有一个下拉列表,用户可以通过下拉列表指定服务器 <form:form commandName="generic"> <form:select path="server"> <form:options items="${servers}" itemValue="id" itemLabel="name"/&g

我使用SpringMVC的SimpleFormController和SpringMVC的表单JTL来创建一个表单来编辑通用对象

在我的表单上有一个下拉列表,用户可以通过下拉列表指定服务器

<form:form commandName="generic">
    <form:select path="server">
        <form:options items="${servers}" itemValue="id" itemLabel="name"/>
    </form:select>
</form:form>

我一直在寻找一个如何在没有运气的情况下实现这一点的例子。我相信我需要覆盖SimpleFormController中的某些内容,就像我在中所做的那样,但是SpringMVC的文档在细节上是轻描淡写的。有人能帮我吗?

我想你是对的。您需要像以前一样在活页夹上注册自定义编辑器,以便将字符串转换为服务器实例。Spring参考文档中有一个自定义PropertyEditor的示例,您可以从中开始


我同意MVC文档不是最好的。我不得不在Spring论坛上进行大量的谷歌搜索和搜索。

作为对Mark答案的补充,以下是我在控制器中完成的工作

@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
    binder.registerCustomEditor(Server.class, "serverId", new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            Server type = (Server) em.createNamedQuery("Server.findById")
                .setParameter("id", Short.parseShort(text)).getSingleResult();
            setValue(type);
        }
    });
}
您也可以使用Spring注入来实现这一点,而不是匿名类。马克的回答中概括了这一点

您还可以扩展ClassEditor(见下文),而不是PropertyEditorSupport。Javadoc声明

java.lang.Class的属性编辑器,以支持类属性的直接填充,而无需使用字符串类名属性作为桥

我不知道我是否完全理解这一点的好处,但要记住一些事情

有用的Javadocs
另一个例子:

使用“server.id”可能是一个可行的解决方案。所以spring会自动绑定所选值,反之亦然

<form:form commandName="generic">
    <form:select path="server.id">
        <form:options items="${servers}" itemValue="id" itemLabel="name"/>
    </form:select>
</form:form>

控制器中答案的注释版本:

@org.springframework.web.bind.annotation.InitBinder("yourFormName")
protected void initBinder(
             org.springframework.web.bind.WebDataBinder binder) {
    binder.registerCustomEditor(Server.class, "serverId", new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            Server s = ...; // do whatever needed to convert
            setValue(s);
        }
    });

谢谢你,马克。在本例中,与其说文档稀疏,不如说信息在我不想在(验证)中查找的部分中。请同时考虑PropertyEditor是statefull的,因此它不是线程安全的。看起来Spring以某种方式处理了它,它永远不会在不同的线程中同时调用同一个属性编辑器,但这会导致请求处理速度变慢,因为它一次只处理一个请求。我今天做了这个观察。春季3.1.2。所以我决定不使用PropertyEditor,而是使用格式化程序方法,而不是使用链接已失效的方法。您可以在这里包括示例的重要部分。
@org.springframework.web.bind.annotation.InitBinder("yourFormName")
protected void initBinder(
             org.springframework.web.bind.WebDataBinder binder) {
    binder.registerCustomEditor(Server.class, "serverId", new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            Server s = ...; // do whatever needed to convert
            setValue(s);
        }
    });