Converting from String to custom Object for Spring MVC form Data binding?

时光总嘲笑我的痴心妄想 提交于 2019-11-26 12:23:17

问题


I am using Spring MVC\'s SimpleFormController in conjunction with Spring MVC\'s form JTL to create a form to edit a Generic object.

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.

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.

I am using JPA as my persistence layer and JPA generated entity classes as my ORM pojos.

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?


回答1:


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 here in the Spring reference docs that should get you started.

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.




回答2:


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 link in Mark's answer.

You you may also be able to extend ClassEditor (see below) instead of PropertyEditorSupport. The Javadoc states;

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.

Don't know if I fully understand the benefit of this, but something to keep in mind.

Useful Javadocs

  • Property Editor Support
  • Spring Data Binder
  • Spring Property Editors
  • Spring Class Editor



回答3:


Using "server.id" can be a possible solution. So spring automatically binds selected value or vice versa.

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



回答4:


Another example:

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




回答5:


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);
        }
    });


来源:https://stackoverflow.com/questions/912257/converting-from-string-to-custom-object-for-spring-mvc-form-data-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!