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?
Spring MVC provides one more annotation, @ModelAttributes , for binding data to the Command object. It is another way to bind the data and to customize the data binding. This annotation allows you to control the creation of the Command object.
Data binding is useful for allowing user input to be dynamically bound to the domain model of an application (or whatever objects you use to process user input). Spring provides the so-called DataBinder to do exactly that.
Interface WebMvcConfigurer. Defines callback methods to customize the Java-based configuration for Spring MVC enabled via @EnableWebMvc . @EnableWebMvc -annotated configuration classes may implement this interface to be called back and given a chance to customize the default configuration.
Examples of formatters are DateFormatter , for parsing String to java. util. Date and formatting a Date . In addition, formatters' messages can be localized. Conclusion: formatters are suitable in the web environment, such as a Spring MVC application.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With