小工具根据定义的白名单字段进行Bean的拷贝

Posted nick-huang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小工具根据定义的白名单字段进行Bean的拷贝相关的知识,希望对你有一定的参考价值。

背景

Bean的拷贝一直有一些类可以使用,比如Apache的org.apache.commons.beanutils.BeanUtils或者Spring的org.springframework.beans.BeanUtils

根据定义的白名单字段进行Bean的拷贝

我需要一个只拷贝我指定的字段的Bean拷贝,而Spring的org.springframework.beans.BeanUtils提供如下几个方法:
技术分享图片
其中第2、3个是可以指定属性的,第2个指定可以通过Class指定,基本满足我的需求;第3个指定无须理会的字段。

我不想定义另外的类,或者另外的父类去指定部分属性,我想通过自己配置的白名单只拷贝白名单指定的属性:

package com.nicchagil.exercise.springbootexercise.util;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.BeanUtils;

public class BeanCopyUtils {
    
    /**
     * 根据白名单字段拷贝Bean
     */
    public static <T> T copyProperties(Object source, Class<T> clazz, String[] whiteProperties) {
        List<String> ignorePropertiesList = BeanCopyUtils.getIgnoreProperties(clazz, whiteProperties);
        
        String[] ignoreProperties = new String[ignorePropertiesList.size()];
        ignorePropertiesList.toArray(ignoreProperties);
        
        T target;
        try {
            target = clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException("通过Class实例化对象发生异常", e);
        }
        
        BeanUtils.copyProperties(source, target, ignoreProperties);
        return target;
    }
    
    /**
     * 根据白名单字段字段获取无须理会的字段
     * @param clazz
     * @param whiteProperties
     * @return
     */
    public static List<String> getIgnoreProperties(Class<?> clazz, String[] whiteProperties) {
        List<String> allProperties = BeanCopyUtils.getAllProperties(clazz);
        
        if (allProperties == null || allProperties.size() == 0) {
            return null;
        }
        
        allProperties.removeAll(Arrays.asList(whiteProperties));
        return allProperties;
    }
    
    /**
     * 获取全部属性名称
     */
    public static List<String> getAllProperties(Class<?> clazz) {
        PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(clazz);
        
        if (propertyDescriptors == null || propertyDescriptors.length == 0) {
            return null;
        }
        
        List<String> properties = new ArrayList<String>();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            properties.add(propertyDescriptor.getName());
        }
        
        return properties;
    }

}

单元测试:

package com.nicchagil.exercise.springbootexercise;

import org.junit.Test;

import com.nicchagil.exercise.springbootexercise.util.BeanCopyUtils;

public class BeanCopyUtilsTest {
    
    @Test
    public void test() {
        User user = new User();
        user.setId(123);
        user.setName("Nick Huang");
        
        User userCopy = BeanCopyUtils.copyProperties(user, User.class, new String[] {"name"});
        System.out.println("user : " + user);
        System.out.println("userCopy : " + userCopy);
    }
    
    public static class User {
        private Integer id;
        private String name;
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "User [id=" + id + ", name=" + name + "]";
        }
    }

}

以上是关于小工具根据定义的白名单字段进行Bean的拷贝的主要内容,如果未能解决你的问题,请参考以下文章

java中如何根据查询出来的表结构自动生成bean

Java对象拷贝机制「实战开发专题」高性能使用CGlib实现Bean拷贝(BeanCopier)指南

Phonegap - iphone中的白名单拒绝

Linux将端口设置进防火墙的白名单

消费层上 Azure Function App 的白名单 IP

Google 跟踪代码管理器 API 错误“不是客户端的有效来源:http://localhost 尚未被列入客户端 ID 的白名单