it-source

스프링 프레임워크 BeanUtils copyProperties를 사용하여 null 값을 무시하는 방법은 무엇입니까?

criticalcode 2023. 8. 14. 22:56
반응형

스프링 프레임워크 BeanUtils copyProperties를 사용하여 null 값을 무시하는 방법은 무엇입니까?

Spring Framework를 사용하여 null 값을 무시하고 Object Source에서 Object Dest로 속성을 복사하는 방법을 알고 싶습니다.

나는 실제로 이 코드로 아파치 비뉴틸을 사용합니다.

    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의 게시물에서 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);
}

모델맵퍼를 사용하는 것이 좋습니다.

이것은 당신의 의심을 해결해주는 샘플 코드입니다.

      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로 변경하는 것입니다.

모델 매퍼

모델 매퍼 MVN

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

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

다른 답변은 이 특별한 경우에 예외를 발생시킵니다.

언급URL : https://stackoverflow.com/questions/19737626/how-to-ignore-null-values-using-springframework-beanutils-copyproperties

반응형