Home > Enterprise >  What is the difference between PropertyEditor, Formatter and Converter in Spring?
What is the difference between PropertyEditor, Formatter and Converter in Spring?

Time:03-21

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.

PropertyEditors 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.

PropertyEditors 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 a Class parameter) uses ClassEditor to try to resolve the parameter to a Class 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 the CommandController.

In summary, PropertyEditors 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 PropertyEditors as well:

As discussed in the previous section, core.convert is a general-purpose type conversion system. It provides a unified ConversionService 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) and DataBinder use this system to bind field values. For example, when SpEL needs to coerce a Short to a Long to complete an expression.setValue(Object bean, Object value) attempt, the core.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 to String to support the view rendering process. In addition, you often need to localize String 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 to PropertyEditor 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 a Long. 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. The ConversionService 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 DataBinders 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.

  • Related