Working with Spring MVC
it turns out that I can bind my forms in many different ways and I really feel like I'm getting lost. The parse
and print
methods of a Formatter
are equivalent to those of a PropertyEditorSupport
with a different name (getAsText
and setAsText
). Similarly, I can implement either a GenericConverter
or two Converter<S,T>
s to do exactly the same thing.
I read here in a comment that Formatters
are a replacement for PropertyEditor
, but I haven't found any documentation to support it and it hasn't even been Deprecated neither.
My question is, when it comes to bind data from a form to an object, what is the correct way to do it in spring-mvc
? What is the main difference between PropertyEditor
, Formatter
and Converter
in Spring? What are the use cases for each one? For me it looks like they have the same responsibility.
CodePudding user response:
To help to understand these concepts I would differentiate first the Spring specific functionality from that exposed from Java.
PropertyEditor
s and the related stuff are defined by the JavaBeans Specification.
The specification defines an API, mechanisms and conventions for dealing with objects, objects properties, and everything related to their changes, as events.
PropertyEditor
s are typically used in GUIs to handle the interaction between an UI and the underlying objects model, typically handling the conversion between properties values from/to its String
representation.
Spring itself actually uses different PropertyEditor
implementations and Java Beans conventions in many different situations. For example, from the docs:
A couple of examples where property editing is used in Spring:
Setting properties on beans is done by using
PropertyEditor
implementations. When you use String as the value of a property of some bean that you declare in an XML file, Spring (if the setter of the corresponding property has aClass
parameter) usesClassEditor
to try to resolve the parameter to aClass
object.Parsing HTTP request parameters in Spring’s MVC framework is done by using all kinds of
PropertyEditor
implementations that you can manually bind in all subclasses of theCommandController
.
In summary, PropertyEditor
s allow you for a broader number of use cases.
Now, in the Spring world you need to do a differentiation as well between Spring MVC and Spring Core.
Please, note that both the Convert and the Formatter stuff are defined as core technologies, of relevance to any use case and not limited to the web framework.
The Spring documentation, when describing Spring Field Formatting, provides a great explanation about the purpose of every API/SPI and how they are related to PropertyEditor
s as well:
As discussed in the previous section,
core.convert
is a general-purpose type conversion system. It provides a unifiedConversionService
API as well as a strongly typed Converter SPI for implementing conversion logic from one type to another. A Spring container uses this system to bind bean property values. In addition, both the Spring Expression Language (SpEL) andDataBinder
use this system to bind field values. For example, when SpEL needs to coerce aShort
to aLong
to complete anexpression.setValue(Object bean, Object value)
attempt, thecore.convert
system performs the coercion.Now consider the type conversion requirements of a typical client environment, such as a web or desktop application. In such environments, you typically convert from
String
to support the client postback process, as well as back toString
to support the view rendering process. In addition, you often need to localizeString
values. The more general core.convert Converter SPI does not address such formatting requirements directly. To directly address them, Spring 3 introduced a convenient Formatter SPI that provides a simple and robust alternative toPropertyEditor
implementations for client environments.In general, you can use the Converter SPI when you need to implement general-purpose type conversion logic — for example, for converting between a
java.util.Date
and aLong
. You can use the Formatter SPI when you work in a client environment (such as a web application) and need to parse and print localized field values. TheConversionService
provides a unified type conversion API for both SPIs.
In the specific use case of Spring MVC the framework itself is able to handle simple types when handling the HTTP requests.
Type conversion is automatically applied based on the configured set of converters, although that behavior can be tweaked using DataBinder
s and the aforementioned Formatting system. Please, see the relevant docs.
In a typical use case in which you deal with reading and writing the body of HTTP requests and responses, when using the @RequestBody
, for example, Spring will use a bunch of different pre-configured HttpMessageConverter
implementations: the actual ones registered will depend on your configuration and the libraries imported in your project - say Jackson, for example. I was unable to find that point in the documentation but here is the link to the actual source code.
Please, consider review this related SO question, it could be of help.