Java 如何使用 springframework BeanUtils copyProperties 忽略空值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19737626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to ignore null values using springframework BeanUtils copyProperties?
提问by Fingolricks
I would like to know how to copy the properties from an Object Source to an Object Dest ignoring null values?? using Spring Framework.
我想知道如何将属性从对象源复制到对象目的地而忽略空值??使用 Spring 框架。
I actually use Apache beanutils, with this code
我实际上使用 Apache beanutils,使用此代码
beanUtils.setExcludeNulls(true);
beanUtils.copyProperties(dest, source);
to do it. But now i need to use Spring.
去做吧。但现在我需要使用 Spring。
Any help?
有什么帮助吗?
Thx a lot
多谢
采纳答案by Alfred Xiao
You can create your own method to copy properties while ignoring null values.
您可以创建自己的方法来复制属性,同时忽略空值。
public static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
// then use Spring BeanUtils to copy and ignore null using our function
public static void myCopyProperties(Object src, Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}
回答by Pawe? Kaczorowski
Java 8 version of getNullPropertyNames method from alfredx's post:
alfredx帖子中 getNullPropertyNames 方法的 Java 8 版本:
public static String[] getNullPropertyNames(Object source) {
final BeanWrapper wrappedSource = new BeanWrapperImpl(source);
return Stream.of(wrappedSource.getPropertyDescriptors())
.map(FeatureDescriptor::getName)
.filter(propertyName -> wrappedSource.getPropertyValue(propertyName) == null)
.toArray(String[]::new);
}
回答by Kumar Abhishek
SpringBeans.xml
SpringBeans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="source" class="com.core.HelloWorld">
<property name="name" value="Source" />
<property name="gender" value="Male" />
</bean>
<bean id="target" class="com.core.HelloWorld">
<property name="name" value="Target" />
</bean>
</beans>
Create a java Bean,
public class HelloWorld { private String name; private String gender; public void printHello() { System.out.println("Spring 3 : Hello ! " + name + " -> gender -> " + gender); } //Getters and Setters }
Create Main Class to test
public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("SpringBeans.xml"); HelloWorld source = (HelloWorld) context.getBean("source"); HelloWorld target = (HelloWorld) context.getBean("target"); String[] nullPropertyNames = getNullPropertyNames(target); BeanUtils.copyProperties(target,source,nullPropertyNames); source.printHello(); } public static String[] getNullPropertyNames(Object source) { final BeanWrapper wrappedSource = new BeanWrapperImpl(source); return Stream.of(wrappedSource.getPropertyDescriptors()) .map(FeatureDescriptor::getName) .filter(propertyName -> wrappedSource.getPropertyValue(propertyName) == null) .toArray(String[]::new); } }
创建一个java Bean,
public class HelloWorld { private String name; private String gender; public void printHello() { System.out.println("Spring 3 : Hello ! " + name + " -> gender -> " + gender); } //Getters and Setters }
创建主类进行测试
public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("SpringBeans.xml"); HelloWorld source = (HelloWorld) context.getBean("source"); HelloWorld target = (HelloWorld) context.getBean("target"); String[] nullPropertyNames = getNullPropertyNames(target); BeanUtils.copyProperties(target,source,nullPropertyNames); source.printHello(); } public static String[] getNullPropertyNames(Object source) { final BeanWrapper wrappedSource = new BeanWrapperImpl(source); return Stream.of(wrappedSource.getPropertyDescriptors()) .map(FeatureDescriptor::getName) .filter(propertyName -> wrappedSource.getPropertyValue(propertyName) == null) .toArray(String[]::new); } }
回答by bpedroso
I advise you to use ModelMapper.
我建议你使用 ModelMapper。
This is a sample code that solves your doubt.
这是一个示例代码,可以解决您的疑问。
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setSkipNullEnabled(true).setMatchingStrategy(MatchingStrategies.STRICT);
Company a = new Company();
a.setId(123l);
Company b = new Company();
b.setId(456l);
b.setName("ABC");
modelMapper.map(a, b);
System.out.println("->" + b.getName());
It should print the B value. But if you set the "A" name, the result is a print of "A" value.
它应该打印 B 值。但是,如果您设置“A”名称,结果将打印“A”值。
The secret is changing the value of SkipNullEnabled to true.
秘诀是将 SkipNullEnabled 的值更改为 true。
回答by Kamaljit Sidhu
public static List<String> getNullProperties(Object source) {
final BeanWrapper wrappedSource = new BeanWrapperImpl(source);
return Stream.of(wrappedSource.getPropertyDescriptors())
.map(FeatureDescriptor::getName)
.filter(propertyName -> Objects.isNull(wrappedSource.getPropertyValue(propertyName)))
.collect(Collectors.toList());
回答by sadhen
A better solution based on Pawel Kaczorowski's answer:
基于 Pawel Kaczorowski 的回答的更好的解决方案:
public static String[] getNullPropertyNames(Object source) {
final BeanWrapper wrappedSource = new BeanWrapperImpl(source);
return Stream.of(wrappedSource.getPropertyDescriptors())
.map(FeatureDescriptor::getName)
.filter(propertyName -> {
try {
return wrappedSource.getPropertyValue(propertyName) == null
} catch (Exception e) {
return false
}
})
.toArray(String[]::new);
}
For example, if we have a DTO:
例如,如果我们有一个 DTO:
class FooDTO {
private String a;
public String getA() { ... };
public String getB();
}
Other answers will throw exceptions on this special case.
其他答案将在这种特殊情况下引发异常。