如何使用springframework BeanUtils copyProperties忽略空值?

Fin*_*cks 22 java spring copy notnull

我想知道如何使用Spring Framework将属性从Object Source复制到Object Dest忽略null值.

我实际上使用Apache beanutils,使用此代码

    beanUtils.setExcludeNulls(true);
    beanUtils.copyProperties(dest, source);
Run Code Online (Sandbox Code Playgroud)

去做吧.但现在我需要使用Spring.

有帮助吗?

多谢

Alf*_*iao 55

您可以创建自己的方法来复制属性,同时忽略空值.

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


Paw*_*ski 33

来自alfredx 帖子的 Java 8版本的getNullPropertyNames方法:

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


bpe*_*oso 8

我建议你使用 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());
Run Code Online (Sandbox Code Playgroud)

它应该打印 B 值。但如果您设置“A”名称,则结果是打印“A”值。

秘诀是将 SkipNullEnabled 的值更改为 true。

模型映射器

模型映射器 MVN


Kum*_*hek 5

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>
Run Code Online (Sandbox Code Playgroud)
  1. 创建一个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
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建主类进行测试

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