我的结构类似于下面这样的结构:
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...
}
主要问题是列表的setter方法。如果您尝试使用PropertyMap或甚至使用Providers,您必须使用setter方法,我无法手动创建它们,因为每次运行 mvn eclipse:eclipse 命令时,所有对象都将从wsdl重新生成。
更新:
您可以在以下链接中找到我的源代码: https://github.com/ervinfetic/modelmapper-issue-one
有没有解决方法如何使用Converter?
答案 0 :(得分: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;
}
}
因此,我们希望将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}
如果你有嵌套列表,你可以将命名约定设置为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 isntance:
modelMapper.addConverter(new ListConverter());