Java反射:为集合类型Object调用Setter和Getter方法

Z.I*_*I.J 8 java mapping reflection

我有两个不同的用户定义对象包....

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).
Run Code Online (Sandbox Code Playgroud)

对象层次结构和对象名称在两侧都不同.我想通过字段或通过使用Reflection的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

目标端对象

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;
    }
}   
Run Code Online (Sandbox Code Playgroud)

mal*_*una 8

我认为您可以使用MapStruct在具有不同属性名称的POJO之间进行映射.

但是你的场景很复杂,因为你想要转换ws.lender.dto.CustomerAddressescopl.com.dto.Customer,这意味着将List<ws.lender.dto.PreviousAddress>包含转换为ws.lender.dto.PreviousAddresses对象,Set<copl.com.dto.CustomerAddress>包含到copl.com.dto.Customer对象中.

所以,我会一步一步解释.

1.转换ws.lender.dto.PreviousAddresscopl.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);
}
Run Code Online (Sandbox Code Playgroud)

此接口将PreviousAddress对象映射到CustomerAddress考虑streetNo必须映射到的属性streetNumber.unitNumber属性没有映射,因为没有源.

2.将a转换List<ws.lender.dto.PreviousAddress>Set<copl.com.dto.CustomerAddress>

现在,您必须向现有CustomerAddressesMapper接口添加另一种映射方法:

Set<CustomerAddress> previousToCustomerSet(List<PreviousAddress> addresses);
Run Code Online (Sandbox Code Playgroud)

此方法将使用前者previousToCustomerObject将源列表的每个元素转换为目标集.

3.转换ws.lender.dto.CustomerAddressescopl.com.dto.Customer

最后,您需要将最后一个映射方法添加到CustomerAddressesMapper接口:

@Mappings(@Mapping(source = "previousAddresses.previousAddress", target = "customerAddresses")
Customer customerAddrsToCustomerObject(CustomerAddresses addresses);
Run Code Online (Sandbox Code Playgroud)

这是使用以前的方法映射原始对象,将previousAddresses.previousAddress属性转换为customerAddresses属性的位置.

4.使用映射器

要使用映射器,您必须编写如下代码:

CustomerAddressesMapper mapper = CustomerAddressesMapper.INSTANCE;
CustomerAddresses origin = //Retrieve it from anywhere
Customer dest = mapper.customerAddrsToCustomerObject(origin);
Run Code Online (Sandbox Code Playgroud)

5.设置

MapStruct是一个源代码生成器,因此您需要正确配置pom.xml包含MapStruct依赖项并调用此代码生成.你可以在这里看到如何做到这一点

好吧,我不构建和运行此代码,但这是实现它的方法.

希望能帮助到你!


Z.I*_*I.J 3

I have studied many objects mapping frameworks for this assignments like

Finally I choose the Orika framework to complete that above Objects to Objects mapping. We can do the that mapping via other mapper framework, but I was like Orika framework because this framework very easy to use for mapping Objects to Objects.

I will explain step by step.

1. Create the Objects of Source side Object and Destination side Object.

like this..

    Customer destination = new Customer();
    CustomerAddresses source = new CustomerAddresses();
    source = filledCustomerAddressesObject();
Run Code Online (Sandbox Code Playgroud)

2. Constructing the DefaultMapperFactory

MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
Run Code Online (Sandbox Code Playgroud)

3. Mapping fields

    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);
Run Code Online (Sandbox Code Playgroud)

Its work fine Cheers