Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring conversion service - from List<A> to List<B>

I have registered a custom conversion service in a Spring 3 application. It works well for POJOs but it does not work on Lists.

For example, I convert from String to Role and it works fine, but not for List<String> to List<Role>.

All kind of ClassCastExceptions fly in the application when trying to inject Lists, no matter what they contain. The Conversion service calls the convertor for List<String> to List<Role> for all.

This makes sense if you think about it. Type erasure is the culprit here and the convertion service actually sees List to List.

Is there a way to tell the conversion service to work with generics?

What other options do I have?

like image 663
JohnDoDo Avatar asked Oct 12 '11 09:10

JohnDoDo


2 Answers

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
    }
}
like image 190
ksokol Avatar answered Sep 17 '22 12:09

ksokol


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)));
like image 27
nndru Avatar answered Sep 17 '22 12:09

nndru