我有两个不同的用户定义对象包....
1) ws.lender.dto (all Objects exists in this package are source side).
2) copl.com.dto (all Objects exists in this package are destination side).
对象层次结构和对象名称在两侧都不同。我想去 按源或复制源端对象到目标端对象 使用反射通过getter和setter。
例如
来源对象
package ws.lender.dto;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CustomerAddresses", propOrder = {
"previousAddresses"
})
public class CustomerAddresses {
protected PreviousAddresses previousAddresses;
public PreviousAddresses getPreviousAddresses() {
return previousAddresses;
}
public void setPreviousAddresses(PreviousAddresses value) {
this.previousAddresses = value;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PreviousAddresses", propOrder = {
"previousAddress"
})
public class PreviousAddresses {
@XmlElement(name = "PreviousAddress", required = true)
protected List<PreviousAddress> previousAddress;
public List<PreviousAddress> getPreviousAddress() {
if (previousAddress == null) {
previousAddress = new ArrayList<PreviousAddress>();
}
return this.previousAddress;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PreviousAddress", propOrder = {
"streetNo",
"streetName"
})
public class PreviousAddress {
@XmlElement(name = "StreetNo", required = true)
protected String streetNo;
@XmlElement(name = "StreetName", required = true)
protected String streetName;
public String getStreetNo() {
return streetNo;
}
public void setStreetNo(String value) {
this.streetNo = value;
}
public String getStreetName() {
return streetName;
}
public void setStreetName(String value) {
this.streetName = value;
}
}
目的地方对象
package copl.com.dto;
@javax.persistence.Entity
public class Customer implements java.io.Serializable
{
private Set<CustomerAddress> customerAddresses;
public Set<CustomerAddress> getCustomerAddresses()
{
return customerAddresses;
}
public void setCustomerAddresses(Set<CustomerAddress> customerAddresses)
{
this.customerAddresses = customerAddresses;
}
}
@javax.persistence.Entity
public class CustomerAddress implements java.io.Serializable
{
private String unitNumber;
private String streetName;
private String streetNumber;
public String getUnitNumber()
{
return unitNumber;
}
public void setUnitNumber(String unitNumber)
{
this.unitNumber = unitNumber;
}
public String getStreetName()
{
return streetName;
}
public String getStreetNumber()
{
return streetNumber;
}
public void setStreetName(String streetName)
{
this.streetName = streetName;
}
public void setStreetNumber(String streetNumber)
{
this.streetNumber = streetNumber;
}
}
答案 0 :(得分:8)
我认为你可以使用MapStruct来映射具有不同属性名称的POJO。
但您的方案很复杂,因为您希望将ws.lender.dto.CustomerAddresses
转换为copl.com.dto.Customer
,这意味着将包含在List<ws.lender.dto.PreviousAddress>
内的ws.lender.dto.PreviousAddresses
转换为Set<copl.com.dto.CustomerAddress>
{1}}包含在copl.com.dto.Customer
对象中。
所以,我将逐步解释。
ws.lender.dto.PreviousAddress
转换为copl.com.dto.CustomerAddress
要进行此转换,您需要一个接口(MapStruct将为此创建一个实例),负责从源对象到目标对象的映射:
import ws.lender.dto.PreviousAddress;
import copl.com.dto.CustomerAddress;
@Mapper
public interface CustomerAddressesMapper{
CustomerAddressesMapper INSTANCE = Mappers.getMapper( CustomerAddressesMapper.class );
@Mappings(@Mapping(source = "streetNo", target = "streetNumber")
CustomerAddress previousToCustomerObject(PreviousAddress address);
}
考虑到PreviousAddress
属性必须映射到CustomerAddress
,此界面会将streetNo
对象映射到streetNumber
。 unitNumber
属性没有映射,因为它没有源。
List<ws.lender.dto.PreviousAddress>
转换为Set<copl.com.dto.CustomerAddress>
现在您必须向现有CustomerAddressesMapper
接口添加另一种映射方法:
Set<CustomerAddress> previousToCustomerSet(List<PreviousAddress> addresses);
此方法将使用前一个previousToCustomerObject
将源列表的每个元素转换为目标集。
ws.lender.dto.CustomerAddresses
转换为copl.com.dto.Customer
最后,您需要将最后一个映射方法添加到CustomerAddressesMapper
接口:
@Mappings(@Mapping(source = "previousAddresses.previousAddress", target = "customerAddresses")
Customer customerAddrsToCustomerObject(CustomerAddresses addresses);
这是您使用以前的方法映射原始对象,将previousAddresses.previousAddress
属性转换为customerAddresses
属性的位置。
要使用映射器,您必须编写如下代码:
CustomerAddressesMapper mapper = CustomerAddressesMapper.INSTANCE;
CustomerAddresses origin = //Retrieve it from anywhere
Customer dest = mapper.customerAddrsToCustomerObject(origin);
MapStruct是一个源代码生成器,因此您需要正确配置pom.xml
以包含MapStruct依赖项并调用此代码生成。您可以看到如何执行此操作here
我没有构建和运行此代码,但这是实现此目的的方法。
希望它有所帮助!
答案 1 :(得分:3)
我已经为这个作业研究了很多对象映射框架,比如
最后,我选择Orika框架来完成上面的Objects to Objects映射。我们可以通过其他映射器框架进行映射,但我就像Orika框架,因为这个框架非常容易用于将对象映射到对象。
我将逐步解释。
<强> 1。创建源侧对象和目标端对象的对象。
像这样......Customer destination = new Customer(); CustomerAddresses source = new CustomerAddresses(); source = filledCustomerAddressesObject();
<强> 2。构造DefaultMapperFactory
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
第3。映射字段
ClassMapBuilder<CustomerAddresses, Customer> builder;
builder= mapperFactory.classMap(CustomerAddresses.class, Customer.class).constructorA();
builder.field("previousAddresses.previousAddress{streetNo}","customerAddresses{streetNumber}");
builder.field("previousAddresses.previousAddress{streetName}","customerAddresses{streetName}");
builder.register();
BoundMapperFacade<CustomerAddresses, Customer> boundMapper;
boundMapper = mapperFactory.getMapperFacade(CustomerAddresses.class, Customer.class);
destination = boundMapper.map(source, destination);
它的工作很好干杯
答案 2 :(得分:2)
您可以更好地尝试Object Mapper进行投射或复制。对于其他包中的其他类的对象,您可以添加一些属性值,如
senderClass 和 rvcClass
稍后您可以阅读这些属性并继续转换该类。可能你已经准备好发送者类与接收者类的映射。
答案 3 :(得分:1)
如果我理解正确,您需要一种方法将所有同名的属性从一个对象复制到另一个对象。类似命名的属性可能是源对象有一个名为getPropertyName()的方法,而目标对象有一个名为setPropertyName()的情况。
如果这是正确的,那么您希望使用Apache Commons库中的BeanUtils类的copyProperties方法。文档为here。
现在,在您的示例中,您有一些不相似的相应属性,例如StreetNumber和StreetNo。我担心通过反思自动处理这类事情并不容易;您需要自己定义源属性和目标属性之间的映射,可能通过定义辅助类来进行复制。