问题
I am using Orika 1.4.5, and i want to make my BidirectionalConverter to map
PaginatedResponse<T> to PaginatedResponse<S>
and viceversa.
The PaginatedResponse class is as follows:
public class PaginatedResponse<T> {
private List<T> items;
private List<Sorting> orderBy;
private PagingResponse paging;
public PaginatedResponse(List<T> items, List<Sorting> orderBy, PagingResponse paging) {
this.items = items;
this.orderBy = orderBy;
this.paging = paging;
}
// Getters
}
So i want that my PaginatedResponseCovnerter takes all map calls where conversion is PaginatedResponse<Something> object1 to PaginatedResponse<OtherSomething> object2
, and i want that object1 and object2 have same orderBy and paging attributes. So i try doings this:
public class PaginatedResponseConverter<T, S>
extends BidirectionalConverter<PaginatedResponse<T>, PaginatedResponse<S>>
implements MapperAware {
private MapperFacade mapper;
private T clazz1;
private S clazz2;
public PaginatedResponseConverter(T clazz1, S clazz2) {
this.clazz1 = clazz1;
this.clazz2 = clazz2;
}
@Override
public void setMapper(Mapper mapper) {
this.mapper = (MapperFacade) mapper;
}
@Override
@SuppressWarnings("unchecked")
public PaginatedResponse<S> convertTo(PaginatedResponse<T> source, Type<PaginatedResponse<S>> destinationType) {
System.out.println("ConverTo");
PagingResponse paging = source.getPaging();
List<Sorting> sortings = source.getOrderBy();
List<S> items = (List<S>) this.mapper.mapAsList(source.getItems(), this.clazz2.getClass());
return new PaginatedResponse<S>(items, sortings, paging);
}
@Override
@SuppressWarnings("unchecked")
public PaginatedResponse<T> convertFrom(PaginatedResponse<S> source, Type<PaginatedResponse<T>> destinationType) {
// The same upside down
}
}
But the problem with this is that i have to register this custom converter with generics arguments , and these are not always the same. I want that if i try to convert from PaginatedResponse<SomeClass1> to PaginatedResponse<SomeClass2>
be the same that PaginatedResponse<AnotherClass1> to PaginatedResponse<AnotherClass2>
, and by the way, i cannot do this:
converterFactory.registerConverter(new PaginatedResponseConverter<Object, Object>(Object.class, Object.class));
because by this way all PaginatedResponse calls will get into PaginatedResponseConverter but i dont know the real type from the classes, so when it goes inside the converTo or convertFrom method, that need the exact class of the generic argument to do the mapAsList() method
Can you help me with this?
回答1:
There is this solution based on Orika's TypeBuilder
that creates Type
-s that store their type arguments.
My code will map a PaginatedResponse<Source>
to a PaginatedResponse<Dest1>
and then to a PaginatedResponse<Dest2>
. If you don't mind some generic warnings, here it goes:
Driver class:
public static void main(String[] args) {
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
ConverterFactory converterFactory = mapperFactory.getConverterFactory();
converterFactory.registerConverter(new PaginatedToPaginatedConverter());
PaginatedResponse<Source> sourcePaginatedResponse = createSourceObject();
MapperFacade mapper = mapperFactory.getMapperFacade();
PaginatedResponse dest1PaginatedResponse = mapper.map(sourcePaginatedResponse,
new TypeBuilder<PaginatedResponse<Source>>(){}.build(),
new TypeBuilder<PaginatedResponse<Dest1>>(){}.build());
PaginatedResponse dest2PaginatedResponse = mapper.map(sourcePaginatedResponse,
new TypeBuilder<PaginatedResponse<Source>>(){}.build(),
new TypeBuilder<PaginatedResponse<Dest2>>(){}.build());
}
Converter, observe that I did not bother to generify PaginatedResponse
, instead I overrode canConvert
:
public class PaginatedToPaginatedConverter extends BidirectionalConverter<PaginatedResponse, PaginatedResponse> {
public PaginatedResponse convertTo(PaginatedResponse paginatedResponse, Type<PaginatedResponse> destinationType) {
PaginatedResponse dest = new PaginatedResponse();
dest.setItems(mapperFacade.mapAsList(paginatedResponse.getItems(),
((Type) destinationType.getActualTypeArguments()[0]).getRawType()));
dest.setOrderBy(mapperFacade.mapAsList(paginatedResponse.getOrderBy(), Sorting.class));
dest.setPaging(mapperFacade.map(paginatedResponse.getPaging(), PagingResponse.class));
return dest;
}
public PaginatedResponse convertFrom(PaginatedResponse paginatedResponse, Type<PaginatedResponse> destinationType) {
return null;
}
@Override
public boolean canConvert(Type<?> sourceType, Type<?> destinationType) {
return sourceType.getRawType().equals(PaginatedResponse.class)
&& destinationType.getRawType().equals(PaginatedResponse.class);
}
}
来源:https://stackoverflow.com/questions/29615401/how-to-map-generics-objects-with-orika