Bean对象之间属性复制

在使用Spring的BeanUtils 复制属性时会存在一个问题,就是源对象的属性会全部覆盖带目标对象上,即使源对象的属性为null,就像下面这样.

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class Amazon{
        private String site;
        private String productName;
        private BigDecimal price;
        private String telNumber;
        private String shipmentName;
    }


    @Test
    public void copy(){
        Amazon amazon = new Amazon();
        amazon.setPrice(BigDecimal.valueOf(50.22));
        amazon.setSite("US");
        amazon.setShipmentName("James");

        Amazon amazonCopy = new Amazon();

        amazonCopy.setTelNumber("01-845754-451524");
        amazonCopy.setProductName("Computer");

        System.out.println("before "+amazonCopy);
        BeanUtils.copyProperties(amazon,amazonCopy);

        System.out.println("after "+amazonCopy);
    }

输出

before TestClass.Amazon(site=null, productName=Computer, price=null, telNumber=01-845754-451524, shipmentName=null)
after TestClass.Amazon(site=US, productName=null, price=50.22, telNumber=null, shipmentName=James)

明显看到了amazonCopy原来的telNumber和productName 的内容都被覆盖了,但是想要目标对象的属性存在的不被覆盖,需要怎么做呢?其实BeanUtils提供了了三个参数copyProperties方法,最后一个就是不需要复制属性名。

那么可以基于这个操作,实现目标对象存在的属性不需要被覆盖。

    @Test
    public void copy(){
        Amazon amazon = new Amazon();
        amazon.setPrice(BigDecimal.valueOf(50.22));
        amazon.setSite("US");
        amazon.setShipmentName("James");

        Amazon amazonCopy = new Amazon();

        amazonCopy.setTelNumber("01-845754-451524");
        amazonCopy.setProductName("Computer");

        System.out.println("before "+amazonCopy);
        BeanUtils.copyProperties(amazon,amazonCopy,getNonNullPropertyNames(amazonCopy));

        System.out.println("after "+amazonCopy);
    }

    /**
     * Get fields whose attributes are not null
     *
     * @param source meta data
     * @return not null filed value
     */
    public static String[] getNonNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<>();
        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue != null) {
                emptyNames.add(pd.getName());
            }
        }
        return emptyNames.toArray(new String[0]);
    }
before TestClass.Amazon(site=null, productName=Computer, price=null, telNumber=01-845754-451524, shipmentName=null)
after TestClass.Amazon(site=US, productName=Computer, price=50.22, telNumber=01-845754-451524, shipmentName=James)

可以看到属性存在值得没有被替换成null。

posted @ 2024-11-07 18:56  lyu6  阅读(88)  评论(0)    收藏  举报