一尘不染

从String转换为Spring MVC表单的自定义对象数据绑定?

spring

我将Spring MVC的SimpleFormController与Spring MVC的表单JTL结合使用,以创建用于编辑Generic对象的表单。

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

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

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

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

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

不幸的是,当我提交表单时,这似乎无法正确绑定,因为它无法从String转换为Server。

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的文档对细节不多。有谁可以帮我离开这里吗?


阅读 470

收藏
2020-04-14

共2个答案

一尘不染

我认为你是对的。你需要像之前一样在活页夹上注册一个自定义编辑器,以便可以将String转换为Server实例。有一个自定义的属性编辑器的例子这里在Spring参考文档,应该让你开始。

我同意MVC文档不是最好的。我不得不在spring论坛上做很多谷歌搜索和搜索工作。

2020-04-14
一尘不染

作为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的属性编辑器,用于启用直接填充Class属性,而不必依赖于使用String类名属性作为桥。

2020-04-14