【小工具】根据定义的白名单字段进行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 + "]";
        }
    }

}

原文地址:https://www.cnblogs.com/nick-huang/p/8150597.html

时间: 2024-10-13 18:26:51

【小工具】根据定义的白名单字段进行Bean的拷贝的相关文章

找回存储过程创建定义的小工具

找回存储过程创建定义的小工具 最近在开发过程中,由于数据库内的存储过程太多,100+张表,每张表都有CRUD的存储过程,还有别的存储过程,并且由于业务需求的变动,需要不断改写存储过程. 因为大家都对同一个测试库做修改,经常出现不同开发人员的存储过程互相覆盖的情况,拖慢了开发进度,通过在网上的查找 找到了一款Source Safe for SQL Server来协助我们解决该类问题,下面简单写一下我们如何使用Source Safe for SQL Server保存历史数据库对象定义. 下载该工具可

【Qt5开发及实例】18、图形修饰小工具

图形修饰小工具 无力吐槽,这是我第三遍写这个了,到底是个什么意思???我只要一贴代码,浏览器直接崩溃,呵呵了,我也是,我现在只要写完一段字我就保存,尼玛在掉我就不写了,写到word里面,再贴上来. 效果 左边图形展示界面 paintarea.h /** * 书本:[Qt5开发及实例] * 功能:实现绘画各种图形 * 文件:paintarea.h * 时间:2015年1月21日16:59:25 * 作者:cutter_point */ #ifndef PAINTAREA_H #define PAI

Android 开发小工具之:Tools 属性 (转)

Android 开发小工具之:Tools 属性 http://blog.chengyunfeng.com/?p=755#ixzz4apLZhfmi 今天来介绍一些 Android 开发过程中比较有用但是大家又不常用的小工具.这些小工具可以提高 Android 应用开发的效率.还可以提高代码质量.所以还是有必要使用的. 首先介绍布局文件中的 tools 属性. 如果你用 Android Studio 创建一个简单的示例项目,在生成的布局文件中会有这么一行内容: xmlns:tools="http:

mfc小工具开发之定时闹钟之---多线程急线程同步

一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等.用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等.但对于Win32的API编程而言,这两种线程是没有区别的,它们都只需线程的启动地址即可启动线程来执行任务. 在MFC中,一般用全局函数Afx

前端工程师都用哪些靠谱的小工具?

前端工程师都用哪些靠谱的小工具? 转载自 作者 杜Amy 现在市场上可用的前端开发工具实在是数不胜数,令人眼花缭乱,作为一个已入坑的前端开发工程师,再此分享一下自己用过的一些工具库. 前端小工具 说到开发工具,肯定是少不了编辑器: SublimeText SublimeText SublimeText 这个工具很火,关键在于它的小巧.简洁.快枪手,长长的文本打开速度也是杠杠的.具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等.还可自定义键绑定,菜单和工具栏.是一个跨平

Windows虚拟地址转物理地址(原理+源码实现,附简单小工具)

                                                                                                     By Lthis 上个月就想写了,一直没时间...网上大概搜了一下,原理与操作倒是一大堆,一直没看到源码实现,总得有人动手,这回轮到我了.东西写得很烂,请大牛勿喷.一直觉得靠源码的方式驱动学习是非常好的一种学习方法,比较直观!声明一下,本教程只有讨论开启PAE与关闭PAE两种,至于PSE是否开启没

[apue] 一个查看当前终端标志位设置的小工具

话不多说,先看运行效果: >./term input flag 0x00000500 BRKINT not in ICRNL IGNBRK not in IGNCR not in IGNPAR not in IMAXBEL not in INLCR not in INPCK not in ISTRIP not in IUCLC not in IXANY not in IXOFF not in IXON PARMRK not in output flag 0x00000005 BSDLY not

手把手教你做音乐播放器(八)桌面小工具(上)

第8节 桌面小工具 桌面小工具是可以放置在主界面的.快速控制应用的小助手.例如我们的音乐小工具,它可以帮助用户在桌面上就完成音乐的暂停.播放.切换等操作,而不需要启动应用本身. 在安卓系统中,我们也常常叫它App widget. 实现一个App widget要经过以下几个步骤, 创建一个App widget类,让它继承自AppWidgetProvider,例如AnddleMusicAppWidget类: 放在res\layout目录下,为App widget的界面定义一个布局,例如anddle_

这些小工具让你的Android 开发更高效

在做Android 开发过程中,会遇到一些小的问题,虽然自己动手也能解决,但是有了一些小工具,解决这些问题就得心应手了,今天就为大家推荐一下Android 开发遇到的小工具,来让你的开发更高效. Vysor Vysor 是一个可以将手机的屏幕投影到电脑上,当然也可以操作,当我们做分享或者演示的时候,这个工具起到了作用. Vector Asset Android Studio 在1.4 支持了VectorAsset,所谓VectorAsset:它可以帮助你在Android 项目中添加Materia