/media/2023/12/spring-using-conversionservice.avif

This tutorial shows you how to use ConversionService in Spring framework.

Java is a strongly-typed language which requires variables to have a type. Sometimes, we need to convert the type of a variable to another one. Java already has built-in methods for converting a variable to another type. For example, you can use Integer.parseInt to convert the type to an integer. However, that requires you to use different methods for different types. If you use the Spring framework, you can use ConversionService, which supports conversion between various types. This can be useful if you have to handle conversion of various types.

Using ConversionService

To use the ConversionService, you only need to inject an instance of it to any Spring bean. By default, if you use Spring Web MVC or WebFlux, there should be a bean of type DefaultFormattingConversionService, which is a sub type of ConversionService. It will be the one that's autowired by Spring unless you create a custom conversion service.

  @Service
  public class MyService {
  
    private final ConversionService conversionService;
  
    public MyService(ConversionService conversionService) {
      this.conversionService = conversionService;
    }
  }

Convert Value

To convert an object to another type, call one of the convert methods below. The first method requires you to specify the target type. To use the second method, you have to pass the TypeDescriptor of the source type and target type.

  <T> T convert(@Nullable Object source, Class<T> targetType);
  Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType);

Let's assume we use the DefaultFormattingConversionService, which is the default one. It can only perform type conversions between certain types. The DefaultFormattingConversionService itself uses DefaultConversionService, in which you can see the list of registered converters. The registered converter classes are located in the org.springframework.core.convert.support package.

For example, an Integer value can be converted to a String using ObjectToStringConverter or a List using ObjectToCollectionConverter.

  String convertedValue1 = this.conversionService.convert(1, String.class);
  List<Integer> convertedValue2 = this.conversionService.convert(1, List.class);

Output:

  1 (String)
  [1] (List)

In the example below, there is no converter for converting an Integer to a Boolean. As a result, it will throw ConverterNotFoundException.

  Boolean value = this.conversionService.convert(1, Boolean.class); // throw ConverterNotFoundException

Below are the corresponding examples that pass the TypeDescriptor for the source and target types. Despite it's annotated with @Nullable, the sourceType argument must be passed unless the source object is null.

 Integer value = 1;
  String convertedValue3 = (String) this.conversionService.convert(
      value,
      TypeDescriptor.forObject(value),
      TypeDescriptor.valueOf(String.class)
  );
  List<Integer> convertedValue4 = (List<Integer>) this.conversionService.convert(
      value,
      TypeDescriptor.forObject(value),
      TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class))
  );

Check if the Types Convertible

If the type of the value to be converted can be dynamic, you may want to check first whether the conversion can be performed. For that purpose, you can call the canConvert method. You can either pass the Class or the TypeDescriptor of source and target types.

  boolean canConvert(@Nullable Class<?> sourceType, Class<?> targetType);
  boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType);

Below are the usage examples.

  boolean isConvertible1 = this.conversionService.canConvert(Integer.class, String.class);
  boolean isConvertible2 = this.conversionService.canConvert(Integer.class, Boolean.class);
  boolean isConvertible3 = this.conversionService.canConvert(TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(String.class));
  boolean isConvertible4 = this.conversionService.canConvert(TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(Boolean.class));

Output:

  true
  false
  true
  false

Summary

In this tutorial, we have learned how to use ConversionService in Spring framework. It can be used to convert a value to another type by defining the class or TypeDescriptor. It also provides methods for checking whether type conversion can be performed.