Spring conversion service - from List<A> to List<B>
I've encountered same problem, and by performing a little investigation find a solution (works for me). If you have two classes A and B, and have a registered converter e.g. SomeConverter implements Converter, than, to convert list of A to list of B you should do next:
List<A> listOfA = ...
List<B> listOfB = (List<B>)conversionService.convert(listOfA,
TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(A.class)),
TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(B.class)));
Another way to convert from List<A>
to List<B>
in Spring is to use ConversionService#convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType)
. Javadoc
This approach just needs a Converter<A,B>
.
Call to conversionService for collection types:
List<A> source = Collections.emptyList();
TypeDescriptor sourceType = TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(A.class));
TypeDescriptor targetType = TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(B.class));
List<B> target = (List<B>) conversionService.convert(source, sourceType, targetType);
The converter:
public class ExampleConverter implements Converter<A, B> {
@Override
public B convert(A source) {
//convert
}
}
I'm using the Spring GenericConversionService.
The convert method in question has the following signature:
public <T> T convert(Object source, Class<T> targetType)
List<B>.class
is not valid Java syntax.
This worked for me:
List<A> sourceList = ...;
conversionService.convert(sourceList, (Class<List<B>>)(Class<?>)List.class);
Got the idea from here: StackOverflow - Class object of generic class
Edit:
The above did not truly work. No compile errors, however it resulted in the sourceList not being converted, and being assigned to the targetList. This resulted in various exceptions downstream while attempting to use the targetList.
My current solution is to extend Spring's GenericConversionService and add my own convert method to handle lists.
Here's the convert method:
@SuppressWarnings({"rawtypes", "unchecked"})
public <T> List<T> convert(List<?> sourceList, Class<T> targetClass) {
Assert.notNull(sourceList, "Cannot convert null list.");
List<Object> targetList = new ArrayList();
for (int i = 0; i < sourceList.size(); i++) {
Object o = super.convert(sourceList.get(i), targetClass);
targetList.add(o);
}
return (List<T>) targetList;
}
And it can be called like the following:
List<A> sourceList = ...;
List<B> targetList = conversionService.convert(sourceList, B.class);
Love to see if anyone has a better way to handle this common scenario.