我有类似这样的结构如下:
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());