Spring conversion: converters and formatters, part 2

Converter<,>

The Converter concept is a more general one, it allows you to convert data between any two types. This means that you can use not only for the web-layer for converting from String but some more general conversion logic. Let's start with this type-to-type example...

ConversionService direct usage

First, we would need the target property to be converted, let’s use for it the enum BookStatus:

No converter found capable of converting from type [java.lang.Long] to type [com.example.demo.model.BookStatus]

Registering

Now, we need to register our converter somehow. We can either create the bean of ConverstionService by means ofConverstionServiceFactoryBean or directly instantiating the@Bean of that type.

c.e.d.c.LongBookStatusConverter          : Converting 1
com.example.demo.DemoApplication : Runner... status after conversion: FORBIDDEN

Formatter

Ok, that was nice. Now let’s talk a bit about the last but not least option for conversion — . As it’s written in the documentation, this concept is dedicated to the conversion in client-facing interfaces (like our Web app, for example). It can be used for converting from String and use the Locale of the client to provide integration with i18n.

curl --location --request POST 'localhost:8099/book' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'id=123' \
--data-urlencode 'author=Alex' \
--data-urlencode 'issueDate=1592009798000'
Field error in object 'book' on field 'issueDate': rejected value [1592009798000]

Registering

The registration could be done by means of:

  • just creating a bean from formatter class, if it’s a boot-application;
  • creating FormattingConversionService directly or;
  • usingFormattingConversionServiceFactoryBean, which in the end is the same;
  • directly in controller binder method (@InitBinder and WebDataBinder);
  • using WebMvcConfigurer, which is broadly being used to configure MVC-specific stuff.
c.e.demo.formatters.IssuedDateFormatter  : Parsing date from 1592009798000  c.e.demo.controllers.GeneralController   : Created book: com.example.demo.model.Book(123, Sat Jun 13 02:56:38 CEST 2020, com.example.demo.model.Author(Alex), null)

Annotation-driven formatting

Finishing the topic with formatters, I should mention the subclass of it — AnnotationFormatterFactory This is a very convenient way of applying conversion according to the custom annotation, which could be put just right on top of the field. This approach is very explicit and allows us to see the conversion configuration in place - in your model data.

public class MyModel {

@DateTimeFormat(iso=ISO.DATE)
private Date date;
}

Conclusion

These type conversion concepts are basic things in Spring, but they lay down in the foundation of many other abstractions and services, which people get from Spring. Thus, it’s quite important to understand them well and be able to use them. I hope this reading helped to build a more structured picture of Spring type conversion option for you.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store