将字符串转换为 Spring MVC 表单数据绑定的自定义对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/912257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting from String to custom Object for Spring MVC form Data binding?
提问by James McMahon
I am using Spring MVC's SimpleFormController in conjunction with Spring MVC's form JTL to create a form to edit a Generic object.
我将 Spring MVC 的 SimpleFormController 与 Spring MVC 的表单 JTL 结合使用来创建一个表单来编辑通用对象。
On my form I have a drop down where the user can specify a server via a drop down.
在我的表单上,我有一个下拉列表,用户可以在其中通过下拉列表指定服务器。
<form:form commandName="generic">
<form:select path="server">
<form:options items="${servers}" itemValue="id" itemLabel="name"/>
</form:select>
</form:form>
Servers here is propagated by a database call for all available servers. server is a Server ORM pojo, that is a sub-object of another ORM pojo (Generic) that serves as my form backing object.
此处的服务器由所有可用服务器的数据库调用传播。server 是一个 Server ORM pojo,它是另一个 ORM pojo(通用)的子对象,用作我的表单支持对象。
My goal here is to change Generic's server reference, which is represented on the database level as a Foreign Key to the server table.
我的目标是更改 Generic 的服务器引用,它在数据库级别表示为服务器表的外键。
I am using JPA as my persistence layer and JPA generated entity classes as my ORM pojos.
我使用 JPA 作为我的持久层,使用 JPA 生成的实体类作为我的 ORM pojo。
Unfortunately this doesn't seem to be binding properly when my form submits, as it can't translate from String to 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 {}
I've been looking for an example of how to accomplish this with no luck. I believe I need to overwrite something within the SimpleFormController, like I did in this question, but Spring MVC's documentation is light on details. Can anyone help me out here?
我一直在寻找如何在没有运气的情况下完成此任务的示例。我相信我需要在 SimpleFormController 中覆盖一些东西,就像我在这个问题中所做的那样,但是 Spring MVC 的文档对细节很不了解。有人可以帮我从这里出去吗?
采纳答案by Mark
I think you are correct. You need to register a custom editor on the binder like you done before so you can convert a String to a Server instance. There is an example of a custom PropertyEditor herein the Spring reference docs that should get you started.
我认为你是对的。您需要像以前一样在活页夹上注册一个自定义编辑器,以便将 String 转换为 Server 实例。有一个自定义的属性编辑器的例子这里在Spring参考文档,应该让你开始。
I agree that the MVC documentation is not the best. I have had to do a lot of Googling and searching on the Spring forums.
我同意 MVC 文档不是最好的。我不得不在 Spring 论坛上进行大量谷歌搜索和搜索。
回答by James McMahon
Just as a supplement to Mark's answer, here is what I ended up doing in my controller.
作为对马克回答的补充,这是我最终在我的控制器中所做的。
@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);
}
});
}
You can also do this using Spring injection, as opposed to anonymous classes. This outlined by the linkin Mark's answer.
您也可以使用 Spring 注入来做到这一点,而不是匿名类。Mark's answer中的链接概述了这一点。
You you may also be able to extend ClassEditor (see below) instead of PropertyEditorSupport. The Javadoc states;
您也可以扩展 ClassEditor(见下文)而不是 PropertyEditorSupport。Javadoc 指出;
Property editor for java.lang.Class, to enable the direct population of a Class property without recourse to having to use a String class name property as bridge.
java.lang.Class 的属性编辑器,可以直接填充 Class 属性,而无需使用 String 类名属性作为桥接器。
Don't know if I fully understand the benefit of this, but something to keep in mind.
不知道我是否完全理解这样做的好处,但要记住一些事情。
Useful Javadocs
有用的 Javadoc
回答by F?rat Kü?üK
Using "server.id" can be a possible solution. So spring automatically binds selected value or vice versa.
使用“server.id”可能是一个可能的解决方案。所以 spring 会自动绑定选定的值,反之亦然。
<form:form commandName="generic">
<form:select path="server.id">
<form:options items="${servers}" itemValue="id" itemLabel="name"/>
</form:select>
</form:form>
回答by Kristo Aun
回答by Ean V
The annotation version of the answer, in your controller:
答案的注释版本,在您的控制器中:
@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);
}
});

