Spring MVC type conversion : PropertyEditor or Converter?
With all these drawbacks, why using Converters ? Am I missing something ? Are there other tricks that I am not aware of ?
No, I think you have very comprehensively described both PropertyEditor and Converter, how each one is declared and registered.
In my mind, PropertyEditors are limited in scope - they help convert String to a type, and this string typically comes from UI, and so registering a PropertyEditor using @InitBinder and using WebDataBinder makes sense.
Converter on the other hand is more generic, it is intended for ANY conversion in the system - not just for UI related conversions(String to target type). For eg, Spring Integration uses a converter extensively for converting a message payload to a desired type.
I think for UI related flows PropertyEditors are still appropriate especially for the case where you need to do something custom for a specific command property. For other cases, I would take the recommendation from Spring reference and write a converter instead(for eg, to convert from a Long id to an entity say, as a sample).
- For to/from String conversions use formatters (implement org.springframework.format.Formatter) instead of converters. It has print(...) and parse(...) methods, so you need only one class instead of two. To register them, use FormattingConversionServiceFactoryBean, which can register both converters and formatters, instead of ConversionServiceFactoryBean.
- The new Formatter stuff has a couple of additional benefits:
- Formatter interface supplies the Locale object in its print(...) and parse(...) methods, so your string conversion can be locale-sensitive
- In addition to the pre-registered formatters, FormattingConversionServiceFactoryBean comes with a couple of handy preregistered AnnotationFormatterFactory objects, that allow you to specify additional formatting parameters via annotation. For example: @RequestParam @DateTimeFormat(pattern="MM-dd-yy") LocalDate baseDate ... It's not very difficult to create your own AnnotationFormatterFactory classes, see Spring's NumberFormatAnnotationFormatterFactory for a simple example. I think this eliminates the need in controller-specific formatters/editors. Use one ConversionService for all controllers and customize the formatting via annotations.
- I agree that if you still needs some controller-specific string conversion, the simplest way is still to use custom property editor. (I tried to call 'binder.setConversionService(...)' in my @InitBinder method, but it fails, since the binder object comes with the 'global' conversion service already set. Seems like per-controller conversion classes are discouraged in Spring 3).