【问题标题】:Lost content for field with type List<Map<String, String>> when mapping using Orika Mapper使用 Orika Mapper 映射时,类型为 List<Map<String, String>> 的字段丢失内容
【发布时间】:2019-11-12 07:42:31
【问题描述】:

有人在映射时遇到List&lt;Map&lt;String, String&gt;&gt; 类型的字段同样的问题吗?我没有例外,但我需要为我的映射器配置什么吗?

情况是我有这个带有这个字段的对象

List<Map<String, String>> aField

aField 字段的内容是:

[
{
"key1" : "val1",
"key2": "val2"
}
]

当对象映射到另一个对象时,该字段的内容丢失给新映射的对象,当我尝试打印时,列表的大小仍然为1但映射的内容为空(下):

[
{}
]

如果有任何帮助,我将不胜感激。谢谢。

代码如下:

这是要映射的类:

public class SampleClass {
    private List<Map<String, String>> aField = new ArrayList<>();
    private String bField;

    public List<Map<String, String>> getaField() {
        return aField;
    }

    public void setaField(List<Map<String, String>> aField) {
        this.aField = aField;
    }

    public String getbField() {
        return bField;
    }

    public void setbField(String bField) {
        this.bField = bField;
    }
}

然后我有一个映射器(我也在使用 spring 框架):

@Component
public class TransactionMapper extends ConfigurableMapper {
}

控制器上的某处(用于测试目的):

@Autowired
    TransactionMapper mapper;

    System.out.println("---------------- SAMPLE CLASS ------------- ");
                    SampleClass s1 = new SampleClass();
                    List<Map<String, String>> aField = Lists.newArrayList();
                    Map<String, String> map = new HashMap<>();
                    map.put("key1", "val1");
                    map.put("key2", "val2");
                    aField.add(map);
                    s1.setaField(aField);
                    s1.setbField("Sample text");

                    System.out.println("****** s1 contents ******");
                    System.out.println("--- s1 aField: " + ", list size: " + s1.getaField().size());
                    s1.getaField().get(0).forEach((k, v) -> System.out.println((k + ":" + v)));
                    System.out.println("--- s1 bField content: " + s1.getbField());
                    System.out.println("****** end of s1 contents ******");

                    SampleClass s2 = new SampleClass();
                    mapper.map(s1, s2);
                    System.out.println("****** s2 contents ******");
                    System.out.println("--- s2 aField: " + ", list size: " + s2.getaField().size());
                    s2.getaField().get(0).forEach((k, v) -> System.out.println((k + ":" + v)));
                    System.out.println("--- s2 bField content: " + s2.getbField());
                    System.out.println("****** end of s2 contents ******");

                    System.out.println("---------------- SAMPLE CLASS ------------- ");

输出:

****** s1 contents ******
--- s1 aField: , list size: 1
key1:val1
key2:val2
--- s1 bField content: Sample text
****** end of s1 contents ******
****** s2 contents ******
--- s2 aField: , list size: 1
--- s2 bField content: Sample text
****** end of s2 contents ******
---------------- SAMPLE CLASS ------------- 

如您所见,s2的aField没有打印内容。

【问题讨论】:

  • 你能分享你的代码吗?
  • 嗨,我用代码编辑了我的帖子

标签: java orika


【解决方案1】:

经过一番研究,我找到了以下解决方案:

  • 使用 CustomMapper 而不是 ConfigurableMapper。
  • 别忘了创建映射器工厂。

首先将这个添加到 TransactionMapper 类中:

public class TransactionMapper extends ConfigurableMapper{

    public TransactionMapper(MapperFactory f) {
        configure(f);
    } 

    public void configure(MapperFactory f) {
        f.classMap(SampleClass.class, SampleClass.class).customize(new CustomMapper<SampleClass, SampleClass>() {
            //Override mapping method and set source fields to destination fields
            @Override
            public void mapAtoB(SampleClass source, SampleClass destination, MappingContext context) {
                destination.setaField(source.getaField());
                destination.setbField(source.getbField());
            }
        }).byDefault().register();
    }
}

那么你的主类应该是这样的:

...
MapperFactory factory = new DefaultMapperFactory.Builder().build(); //Create the mapper factory
TransactionMapper mapper = new TransactionMapper(factory); //Call the mapper constructor

System.out.println("---------------- SAMPLE CLASS ------------- ");
SampleClass s1 = new SampleClass();
List<Map<String, String>> aField = new ArrayList<Map<String, String>>();
Map<String, String> map = new HashMap<>();
map.put("key1", "val1");
map.put("key2", "val2");
aField.add(map);
s1.setaField(aField);
s1.setbField("Sample text");

System.out.println("****** s1 contents ******");
System.out.println("--- s1 aField: " + ", list size: " + s1.getaField().size());
s1.getaField().get(0).forEach((k, v) -> System.out.println((k + ":" + v)));
System.out.println("--- s1 bField content: " + s1.getbField());
System.out.println("****** end of s1 contents ******");

SampleClass s2 = mapper.map(s1, SampleClass.class);
System.out.println("****** s2 contents ******");
System.out.println("--- s2 aField: " + ", list size: " + s2.getaField().size());
s2.getaField().get(0).forEach((k, v) -> System.out.println((k + ":" + v)));
System.out.println("--- s2 bField content: " + s2.getbField());
System.out.println("****** end of s2 contents ******");

System.out.println("---------------- SAMPLE CLASS ------------- ");
...

输出:

---------------- SAMPLE CLASS ------------- 
****** s1 contents ******
--- s1 aField: , list size: 1
key1:val1
key2:val2
--- s1 bField content: Sample text
****** end of s1 contents ******
****** s2 contents ******
--- s2 aField: , list size: 1
key1:val1
key2:val2
--- s2 bField content: Sample text
****** end of s2 contents ******
---------------- SAMPLE CLASS ------------- 

让我知道它是否有效。如果您有任何问题,请提出,我会尽力回答。如果这有效,请将答案标记为解决方案,以便其他有相同问题的人知道该怎么做。 :)

【讨论】:

  • 您好,感谢您的回复,这实际上是我所做的,对于不完整的细节,我已经用我使用的代码更新了我的帖子。谢谢。
  • 您好,尝试将 SampleClass s2 分配给 mapper.map(s1, SampleClass.class)。我现在将编辑我的答案。
  • 还是一样的输出 :(
  • 让我在我的电脑上测试一下代码,然后我会告诉你的。
猜你喜欢
  • 2017-03-22
  • 1970-01-01
  • 2019-11-27
  • 2020-01-27
  • 2015-06-19
  • 2018-12-07
  • 2011-10-20
  • 2019-10-01
相关资源
最近更新 更多