繁体   English   中英

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

[英]Java Reflection: Invoking Setter and Getter method for collection type Object

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

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).

对象层次结构和对象名称在两侧都不同。 我想通过字段或通过使用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;
    }
}

目标端对象

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;
    }
}   

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

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

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

1.从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属性没有映射,因为它没有源。

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

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

Set<CustomerAddress> previousToCustomerSet(List<PreviousAddress> addresses);

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

3.从ws.lender.dto.CustomerAddresses转换为copl.com.dto.Customer

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

@Mappings(@Mapping(source = "previousAddresses.previousAddress", target = "customerAddresses")
Customer customerAddrsToCustomerObject(CustomerAddresses addresses);

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

4.使用映射器

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

CustomerAddressesMapper mapper = CustomerAddressesMapper.INSTANCE;
CustomerAddresses origin = //Retrieve it from anywhere
Customer dest = mapper.customerAddrsToCustomerObject(origin);

5.设置

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

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

希望能帮助到你!

我已经研究过许多对象映射框架,例如

最后,我选择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);

它的工作很好干杯

您可以更好地尝试使用Object Mapper进行投射或复制。 其他包中的其他类的对象可以添加一些属性值

senderClassrvcClass

稍后您可以阅读这些属性并继续转换该类。 可能你已经准备好发送者类与接收者类的映射。

如果我理解正确,您需要一种方法将所有类似命名的属性从一个对象复制到另一个对象。 类似命名的属性是源对象具有一个名为getPropertyName()的方法,而目标对象有一个名为setPropertyName()的情况。

如果这是正确的,那么您希望使用Apache Commons库中的BeanUtils类的copyProperties方法。 文档在这里

现在,在您的示例中,您有一些不相似的相应属性,例如StreetNumber和StreetNo。 我担心通过反思自动处理这类事情并不容易; 您需要自己定义源属性和目标属性之间的映射,可能通过定义辅助类来进行复制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM