【问题标题】:how to map generics objects with Orika?如何用 Orika 映射泛型对象?
【发布时间】:2015-06-19 08:35:53
【问题描述】:

我正在使用 Orika 1.4.5,我想让我的 BidirectionalConverter 进行映射 PaginatedResponse<T> to PaginatedResponse<S> 反之亦然。

分页响应类如下:

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
}

所以我希望我的 PaginatedResponseCovnerter 接受转换为 PaginatedResponse&lt;Something&gt; object1 to PaginatedResponse&lt;OtherSomething&gt; object2 的所有映射调用,并且我希望 object1 和 object2 具有相同的 orderBy 和 paging 属性。所以我尝试这样做:

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
    }
}

但问题是我必须使用泛型参数注册这个自定义转换器,而这些并不总是相同的。我希望如果我尝试从PaginatedResponse&lt;SomeClass1&gt; to PaginatedResponse&lt;SomeClass2&gt; 转换为与PaginatedResponse&lt;AnotherClass1&gt; to PaginatedResponse&lt;AnotherClass2&gt; 相同,顺便说一句,我不能这样做:

converterFactory.registerConverter(new PaginatedResponseConverter<Object, Object>(Object.class, Object.class));

因为通过这种方式,所有 PaginatedResponse 调用都将进入 PaginatedResponseConverter 但我不知道类的真实类型, 所以当它进入 converTo 或 convertFrom 方法时,需要泛型参数的确切类来执行 mapAsList() 方法

你能帮我解决这个问题吗?

【问题讨论】:

  • 我担心这是不可能的,因为在反射(Orika 将使用)中,无法检索分配给通用占位符的类;这完全是编译器的事情。
  • 感谢您的回复。你对如何解决这个问题有任何想法吗?我的意思是,也许我应该使用映射器而不是转换器。你认为这会改变什么吗?问候!
  • 否则您将不得不传输此信息,可能是通过另一个包含通用参数的类或类名的字段。无论您使用哪种工具,反射的一般问题都是一样的。

标签: java generics converter orika


【解决方案1】:

这个解决方案基于 Orika 的 TypeBuilder,它创建了存储其类型参数的 Type-s。

我的代码会将PaginatedResponse&lt;Source&gt; 映射到PaginatedResponse&lt;Dest1&gt;,然后再映射到PaginatedResponse&lt;Dest2&gt;。如果你不介意一些一般性的警告,这里是:

驱动类:

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());
}

转换器,请注意我没有费心去泛化PaginatedResponse,而是覆盖了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);
    }
}

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2019-01-22
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多