简体   繁体   English

使用Dozer的自定义转换器将对象列表映射到另一个列表

[英]Map a list of object to another list using Dozer's custom converters

What I am trying to do is to map a List of entities to a list of their String ids (more or less) using Dozer. 我想要做的是使用Dozer将实体列表映射到它们的字符串ID列表(或多或少)。

Obviously, it implies Custom Converter. 显然,它意味着Custom Converter。 My first idea was to make a converter from MyEntity to a String, and then say to Dozer something like "Map every object of this collection using this converter". 我的第一个想法是从MyEntity转换为String,然后对Dozer说“使用此转换器映射此集合的每个对象”。 But I couldn't figure out how to do so. 但我无法弄清楚如何做到这一点。

So my second idea was to make a converter form a list of entities to a list of string, directly. 所以我的第二个想法是直接将转换器形成一个实体列表到一个字符串列表。 My problem on this idea is that I was strugling on something ridiculous which is to get the type of my list in the constructor, as below (which doesn't work at all): 关于这个想法我的问题是,我正在讨论一些荒谬的事情,即在构造函数中获取我的列表类型,如下所示(这根本不起作用):

public MyEntityListConverter() {
    super(List<MyEntity>.class, List<String>.class);
}

I don't know how to pass an instantiated list's class in a single row wihout declaring anything. 我不知道如何在一行中传递一个实例化列表的类,而不会声明任何内容。

So if someone know either : 所以如果有人知道:

  • How to specify to dozer an object convertor to use in collection mapping 如何指定dozer一个在集合映射中使用的对象转换器
  • How to get instantiated list type 如何获取实例化列表类型
  • A third/better solution to try 尝试的第三种/更好的解决方案

The way you tried is not possible due to generic types. 由于泛型类型,您无法尝试的方式。 And if it was, Dozer cannot detect types at runtime. 如果是,Dozer无法在运行时检测类型。

1st solution with List<> List<> 第一个解决方案

Your converter : 你的转换器:

public class MyEntityToStringConverter extends DozerConverter<MyEntity, String> {
    // TODO constructor + impl
}

Your mapping : 你的映射:

mapping(MyEntityA.class, MyEntityB.class)
.fields("myEntityList", "myStringList",
    hintA(MyEntity.class),
    hintB(String.class));

mapping(MyEntity.class, String.class)
.fields(this_(), this_(), customConverter(MyEntityToStringConverter.class));

2nd solution with list wrappers 带列表包装的第二个解决方案

You can try to create your custom classes extending a list impl. 您可以尝试创建扩展列表impl的自定义类。

public class MyEntityList extends ArrayList<MyEntity> {

}

public class MyStringList extends ArrayList<String> {

}

Change your field in the parent classes you want to map. 更改要映射的父类中的字段。

Your converter : 你的转换器:

public class MyEntityToStringConverter extends DozerConverter<MyEntityList, MyStringList> {
    // TODO constructor + impl
}

Your mapping : 你的映射:

mapping(MyEntityA.class, MyEntityB.class)
.fields("myEntityList", "myStringList", customConverter(MyEntityToStringConverter.class));

另一种选择是

super((Class<List<MyEntity>>) (Class<?>) List.class,(Class<List<String>>) (Class<?>) List.class);

I very much inclined to @Ludovic solution, but there might be a catch as mentioned in my comment up there . 我非常倾向于@Ludovic解决方案,但我的评论中可能有一个问题。

But a slight tweak works for me though - register the custom converter in "configuration" rather than field level. 但是稍微调整一下对我来说 - 在“配置”而不是字段级别注册自定义转换器。 I'm using XML config but it should work with coding config: 我正在使用XML配置,但它应该与编码配置一起使用:

<configuration>
  <custom-converters>
    <converter type="f.q.c.n.MyEntityToStringConverter">
      <class-a>java.lang.String</class-a>
      <class-b>f.q.c.n.MyEntity</class-b>
    </converter>
  </custom-converters>
</configuration>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM