2013-11-02 101 views
12

我想知道如何使用Spring框架將屬性從Object Source複製到Object Dest忽略空值。如何使用springframework BeanUtils copyProperties忽略空值?

其實我使用Apache的BeanUtils,與此代碼

beanUtils.setExcludeNulls(true); 
    beanUtils.copyProperties(dest, source); 

做到這一點。但是現在我需要使用Spring。

任何幫助?

很多

+0

你能不能包括的BeanUtils爲你的Spring項目類路徑的一部分嗎?我不認爲Spring的BeanUtils以這種方式工作。 –

回答

31

您可以創建自己的方法來複制屬性,同時忽略空值。

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 
public static void myCopyProperties(Object src, Object target) { 
    BeanUtils.copyProperties(src, target, getNullPropertyNames(src)) 
} 
+0

這是一個很好的解決方案。我希望這個框架已經安排了一種可以處理這個問題的方法,但是這會很好地工作。謝謝 – Fingolricks

+0

我也一樣。我將這些方法與其他一些自定義實現一起包含在一個新類中。我的新類擴展了BeanUtils類,以便我可以添加其他功能和功能。 – yuva

+0

myCopyProps方法的call sig中存在拼寫錯誤... Object –

18

爪哇8 getNullPropertyNames方法的版本從alfredx的post

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

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

    // Getter和Setter

  • 創建主類測試

    公共類應用{ 公共靜態無效的主要(字串[] args){ ApplicationContext的上下文=新的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); 
    } 
    

    }