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

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甚至使用提供程序,则必须使用setter方法,而我无法手动进行设置,因为每次运行mvn eclipse:eclipse命令时,所有对象都会从wsdl中重新生成。

更新:

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

有什么解决方案如何使用Converter做到这一点?

最佳答案

如果您没有设置员,则可以配置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;
    }

}


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

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


更新

如果您有嵌套列表,则可以将命名约定设置为mutator,以避免出现多个匹配错误,只需像下面这样配置即可:

 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实例中:

modelMapper.addConverter(new ListConverter());

08-15 16:30