使用 BeanUtils.copyProperties 复制特定字段?
Posted
技术标签:
【中文标题】使用 BeanUtils.copyProperties 复制特定字段?【英文标题】:Copy specific fields by using BeanUtils.copyProperties? 【发布时间】:2011-07-02 01:20:44 【问题描述】:springframework.beans.BeanUtils
对复制对象非常有用,我经常使用“ignoreProperties”选项。但是,有时我只想复制特定的对象(基本上,与“忽略属性”相反)。有谁知道我该怎么做?任何帮助将不胜感激。
import org.springframework.beans.BeanUtils;
public class Sample
public static void main(String[] args)
DemoADto demoADto = new DemoADto();
demoADto.setName("Name of Demo A");
demoADto.setAddress("Address of Demo A");
DemoBDto demoBDto = new DemoBDto();
// This is "ignoreProperties" option
// But I want to know how I can copy only name field by using BeanUtils or something.
BeanUtils.copyProperties(demoADto, demoBDto, new String[] "address");
System.out.println(demoBDto.getName());
System.out.println(demoBDto.getAddress());
public class DemoADto
private String name;
private String address;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getAddress()
return address;
public void setAddress(String address)
this.address = address;
public class DemoBDto
private String name;
private String address;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getAddress()
return address;
public void setAddress(String address)
this.address = address;
【问题讨论】:
【参考方案1】:看看这个:BeanPropertyCopyUtil。
例子:
copyProperties(user, systemUser, "first firstName", "last lastName");
您还需要 Apache Commons BeanUtils。
【讨论】:
这不是实现此目的的适当方式。如果你的属性名被修改了怎么办?将其作为字符串传递并不是更好的方法,而是使用 Field[] fields = destination.getClass().getDeclaredFields(); 获取所有字段;并遍历 (Field field : fields) //ur copy stuff here 的字段 这不适用于子属性,假设我想忽略所有名称为“id”的属性。【参考方案2】:如果您不想使用 Commons BeanUtils,您仍然可以通过 BeanWrapper 使用 Spring。
您必须手动循环遍历所有属性,因此您需要创建一个静态辅助方法。
您始终可以复制 copyProperties 正在执行的操作并根据自己的喜好进行调整: http://tinyurl.com/BeanUtils-copyProperties
【讨论】:
【参考方案3】:您可以使用BeanWrapper
技术。这是一个示例实现:
public static void copyProperties(Object src, Object trg, Iterable<String> props)
BeanWrapper srcWrap = PropertyAccessorFactory.forBeanPropertyAccess(src);
BeanWrapper trgWrap = PropertyAccessorFactory.forBeanPropertyAccess(trg);
props.forEach(p -> trgWrap.setPropertyValue(p, srcWrap.getPropertyValue(p)));
或者,如果你真的,真的想使用BeanUtils
,这里有一个解决方案。反转逻辑,通过将完整属性列表与包含进行比较来收集排除项:
public static void copyProperties2(Object src, Object trg, Set<String> props)
String[] excludedProperties =
Arrays.stream(BeanUtils.getPropertyDescriptors(src.getClass()))
.map(PropertyDescriptor::getName)
.filter(name -> !props.contains(name))
.toArray(String[]::new);
BeanUtils.copyProperties(src, trg, excludedProperties);
【讨论】:
BeanWrapper 技术快了 25%。 :) Spring 建议改用PropertyAccessorFactory.forBeanPropertyAccess(Object)
。 source
如何获得 IterableCollection<String>
关于 BeanWrapper 的提示:使用 trgWrap.setAutoGrowNestedPaths(true) 来避免 NullValueInNestedPathException【参考方案4】:
这是一个带有 Spring BeanUtils 类的示例:
public static void copyList(List sourceList,
List targetList, Class targetType)
try
for (Object source : sourceList)
Object target = null;
target = targetType.newInstance();
BeanUtils.copyProperties(source, target);
targetList.add(target);
catch (InstantiationException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
【讨论】:
【参考方案5】:您可以使用 org.springframework.beans.BeanUtils.copyProperties(Object source, Object target, Class editable) throws BeansException
确保目标实现可编辑的接口,该接口定义了将被复制的属性。
【讨论】:
【参考方案6】:beanUtils
有一个重载方法,我们可以在其中传递我们想要忽略的字段数组。
例如。
String[] ignoreProperties= new String[]"field1","field2";
BeanUtils.copyProperties(a, b,ignoreProperties);
【讨论】:
以上是关于使用 BeanUtils.copyProperties 复制特定字段?的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)