22

我将 Spring MVC 的 SimpleFormController 与 Spring MVC 的表单 JTL 结合使用来创建一个表单来编辑通用对象。

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

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

此处的服务器通过对所有可用服务器的数据库调用进行传播。server 是一个 Server ORM pojo,它是另一个 ORM pojo(通用)的子对象,用作我的表单支持对象。

我的目标是更改 Generic 的服务器引用,它在数据库级别表示为服务器表的外键。

我使用 JPA 作为我的持久层,并使用 JPA 生成的实体类作为我的 ORM pojos。

不幸的是,当我的表单提交时,这似乎没有正确绑定,因为它无法从字符串转换为服务器。

Field error in object 'generic' on field 'server': rejected value [1]; codes [typeMismatch.generic.server,typeMismatch.server,typeMismatch.com.generic.orm.jpa.Server,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [generic.server,server]; arguments []; default message [server]]; default message [Failed to convert property value of type [java.lang.String] to required type [com.generic.orm.jpa.Server] for property 'server'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [com.generic.orm.jpa.Server] for property 'server': no matching editors or conversion strategy found], generic=com.generic.orm.jpa.generic[id=3]} and static attributes {}

我一直在寻找一个如何在没有运气的情况下完成此任务的示例。我相信我需要覆盖 SimpleFormController 中的某些内容,就像我在这个问题中所做的那样,但是 Spring MVC 的文档对细节很清楚。有谁可以帮我离开这里吗?

4

5 回答 5

21

作为对马克回答的补充,这就是我最终在控制器中所做的事情。

@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 的属性编辑器,可以直接填充 Class 属性,而无需使用 String 类名属性作为桥梁。

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

有用的 Javadocs

于 2009-05-28T16:08:31.923 回答
18

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

<form:form commandName="generic">
    <form:select path="server.id">
        <form:options items="${servers}" itemValue="id" itemLabel="name"/>
    </form:select>
</form:form>
于 2012-04-20T05:47:02.330 回答
5

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

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

于 2009-05-26T20:55:11.203 回答
1

另一个例子:

http://empire5.com/development/binding-a-custom-object-in-spring-3/

于 2012-01-30T11:49:16.610 回答
1

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

@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);
        }
    });
于 2017-03-22T00:04:25.473 回答