Spring Frameworkを使用して、null値を無視してオブジェクトソースからオブジェクトデストにプロパティをコピーする方法を教えてください。
私は実際にこのコードでApache beanutilsを使用しています
beanUtils.setExcludeNulls(true);
beanUtils.copyProperties(dest, source);
それを行うには。しかし、今私は春を使用する必要があります。
何か助けは?
ありがとう
Null値を無視してプロパティをコピーする独自のメソッドを作成できます。
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));
}
Alfredxの post からの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);
}
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>
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);
}
}
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());
ModelMapperを使用することをお勧めします。
これはあなたの疑問を解決するサンプルコードです。
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());
Bの値を出力する必要があります。ただし、「A」の名前を設定すると、結果は「A」の値の出力になります。
その秘密は、SkipNullEnabledの値をtrueに変更することです。
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);
}
たとえば、DTOがある場合:
class FooDTO {
private String a;
public String getA() { ... };
public String getB();
}
他の回答は、この特別な場合に例外をスローします。