zoukankan      html  css  js  c++  java
  • 【小工具】根据定义的白名单字段进行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 + "]";
    		}
    	}
    
    }
    
  • 相关阅读:
    WPF 进度条
    WPF CPU使用率线性表
    Android annotation
    git 操作
    git 合并指定目录到master
    远程连接mysql报错,ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)解决方案
    centos7 安装python2.7.14 并与原版本共存
    pycahrm 断点调试
    ImportError: No module named Crypto.Cipher 报错解决方法
    python操作 rabbitMQ
  • 原文地址:https://www.cnblogs.com/nick-huang/p/8150597.html
Copyright © 2011-2022 走看看