1

我有类似下面这样的结构:

public class FirstObject {
    private List<SecondObject> myListOne;

    ...only getter method...
    ...no setter method for the list due to it is generated from wsdl 
}

public class SecondObject {
    private List<ThirdObject> myListTwo;

    ...only getter method...
    ...no setter method for the list due to it is generated from wsdl
}

public class ThirdObject {
    private String firstName;
    private String lastName;

    ...setters and getters...
}

主要问题是列表的设置方法。如果您尝试使用 PropertyMap 甚至使用 Providers,您必须使用 setter 方法,而我无法手动创建它们,因为每次运行mvn eclipse:eclipse命令时,所有对象都会从 wsdl 重新生成。

更新

您可以在以下链接中找到我的源代码: https ://github.com/ervinfetic/modelmapper-issue-one

有什么解决方案如何用转换器制作这个吗?

4

1 回答 1

1

如果您没有设置器,您可以配置ModelMapper为按字段访问。只需启用 FieldMatching 和 FieldAccessLevel 就像您的列表属性一样私有

modelMapper.getConfiguration()
  .setFieldMatchingEnabled(true)
  .setFieldAccessLevel(AccessLevel.PRIVATE);

例子:

FirstObject

public class FirstObject {

    private String name;

    private List<FirstObjectList> objectList = new ArrayList<FirstObjectList>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<FirstObjectList> getObjectList() {
        return objectList;
    }
}

FirstObjectList

public class FirstObjectList {

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

}

因此,我们希望映射FirstObjectSecondObject具有完全相同结构(属性)的类:

SecondObject

public class SecondObject {

    private String name;

    private List<SecondObjectList> objectList;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<SecondObjectList> getObjectList() {
        return objectList;
    }

}

SecondObjectList

public class SecondObjectList {

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

然后我们需要创建我们的 ModelMapper 实例并将其配置为字段匹配和私有访问级别。

public void test(){
    ModelMapper mapper = new ModelMapper();
    mapper.getConfiguration().setFieldMatchingEnabled(true);
    mapper.getConfiguration().setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);


    FirstObject firstObject = new FirstObject();
    firstObject.setName("Hola");

    FirstObjectList firstObjectList = new FirstObjectList();
    firstObjectList.setId("1");

    firstObject.getObjectList().add(firstObjectList);

    SecondObject second = mapper.map(firstObject, SecondObject.class);

    assertEquals(firstObject.getName(), second.getName());

    assertEquals(firstObject.getObjectList().size(), second.getObjectList().size());    
    assertEquals(firstObject.getObjectList().get(0).getId(), second.getObjectList().get(0).getId());
}

一切都已完美映射。所以它有效。

  • 输出:

SecondObject{name='Hola', objectList=[SecondObjectList{id='1'}]}

但是,如果尚未启用FieldMatching或将字段访问级别设置为私有,您的列表将不会被映射:

  • 输出:

SecondObject{name='Hola', objectList=null}

更新

如果你有嵌套列表,你可以将命名约定设置为 mutators 以避免多重匹配错误,只需像下面这样配置它:

 modelMapper.getConfiguration()
.setSourceNamingConvention(NamingConventions.JAVABEANS_MUTATOR);

否则,如果您不想通过字段访问来执行此操作,则可以创建一个Converter来处理这种匹配:

public class ListConverter implements Converter<List<SecondObject>, List<ThirdObject>> {

    @Override
    public List<ThirdObject> convert(MappingContext<List<SecondObject>, List<PromoConditionEntity>> context) {
       //A java 8 mapping example
       return context.getSource()
          .stream()
          .map(this::convertToThirdObject)
        .collect(Collectors.toList());
    }

    private ThirdObject convertToThirdObject(SecondObject s) {
       //your impl map SecondObject to ThirdObject
       ...
     }
}

最后,不要忘记将转换器添加到您的模型映射器实例中:

modelMapper.addConverter(new ListConverter());
于 2017-04-06T06:30:55.697 回答