BeanUtils是一个能够快速封装Java对象 工具集

可以在Java Servlet时,用request.getParameterMap() 获取所有的请求参数 得到一个Map 集合

然后创建一个对象。

调用 BeanUtils.populate(对象,map); 这个对象 就被赋值了!

BeanUtils的Maven依赖

        <!-- BeanUtils -->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.4</version>
        </dependency>

JavaBean概念

方法:getter、setter、无参构造方法

属性:setter 和 getter 方法截取后的产物;可以理解成:除方法外的内容

注意事项

  • 只要是JavaBean 就行

功能

  • 快速封装数据

BeanUtils常用方法

  • setProperty(obj,属性名,属性值); 往obj对象设置值。
  • getProperty(obj,属性名); 获取obj的XXX属性。一般我们直接对象.getXXX获取属性。
  • populate(obj,map); 将map的属性映射到对象。

他的核心是使用 get和set方法进行赋值以及读取。

BeanUtils封装的工具 BeanCopyUtil

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * 通用 Bean 拷贝工具(基于 Apache Commons BeanUtils)。
 *
 * 相关包均来自:org.apache.commons。
 *
 * 功能:
 * - 单对象/列表浅拷贝
 * - 忽略 null 字段复制
 * - 字段名映射复制 (sourceName -> targetName)
 * - 分页 PageInfo 泛型转换
 * - 深拷贝(需外部序列化函数)
 * - Bean <-> Map
 * - 差异比较 & 合并
 */
public final class BeanCopyUtil {

    private static final BeanUtilsBean BEAN_UTILS_BEAN;

    static {
        ConvertUtilsBean convertUtilsBean = new ConvertUtilsBean();
        BEAN_UTILS_BEAN = new BeanUtilsBean(convertUtilsBean);
    }

    private BeanCopyUtil() {
    }

    /* ---------- 单对象复制 ---------- */

    /**
     * 浅拷贝单个对象
     *
     * @param source 源对象
     * @param targetClass 目标类型
     * @return 拷贝后的目标对象
     */
    public static <S, T> T copy(S source, Class<T> targetClass) {
        if (source == null) return null;
        try {
            T target = targetClass.getDeclaredConstructor().newInstance();
            BEAN_UTILS_BEAN.copyProperties(target, source);
            return target;
        } catch (Exception e) {
            throw new IllegalStateException("copy failed: " + e.getMessage(), e);
        }
    }

    /**
     * 浅拷贝,指定忽略字段
     *
     * @param source 源对象
     * @param target 目标对象
     * @param ignoreFields 要忽略的字段名
     */
    public static <S, T> void copy(S source, T target, String... ignoreFields) {
        if (source == null || target == null) return;
        Set<String> ignore = ignoreFields == null ? Collections.emptySet() : new HashSet<>(Arrays.asList(ignoreFields));
        try {
            PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(source.getClass());
            for (PropertyDescriptor desc : descriptors) {
                String name = desc.getName();
                if ("class".equals(name) || ignore.contains(name)) continue;

                if (PropertyUtils.isReadable(source, name) && PropertyUtils.isWriteable(target, name)) {
                    try {
                        Object value = PropertyUtils.getProperty(source, name);
                        PropertyUtils.setProperty(target, name, value);
                    } catch (Exception ignored) {
                    }
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("copy failed: " + e.getMessage(), e);
        }
    }

    /**
     * 忽略 null 值的拷贝
     *
     * @param source 源对象
     * @param target 目标对象
     * @param ignoreFields 要忽略的字段名
     */
    public static <S, T> void copyIgnoreNull(S source, T target, String... ignoreFields) {
        if (source == null || target == null) return;
        Set<String> ignore = ignoreFields == null ? Collections.emptySet() : new HashSet<>(Arrays.asList(ignoreFields));
        try {
            PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(source.getClass());
            for (PropertyDescriptor desc : descriptors) {
                String name = desc.getName();
                if ("class".equals(name) || ignore.contains(name)) continue;

                if (PropertyUtils.isReadable(source, name) && PropertyUtils.isWriteable(target, name)) {
                    try {
                        Object value = PropertyUtils.getProperty(source, name);
                        if (value != null) {
                            PropertyUtils.setProperty(target, name, value);
                        }
                    } catch (Exception ignored) {
                    }
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("copyIgnoreNull failed: " + e.getMessage(), e);
        }
    }

    /* ---------- 字段映射复制 ---------- */

    /**
     * 带字段映射的拷贝(源字段名 -> 目标字段名)
     *
     * @param source 源对象
     * @param targetClass 目标类型
     * @param fieldMapping 字段映射关系 (sourceName -> targetName)
     * @param ignoreNullSource 是否忽略源对象中的 null 值
     * @return 拷贝后的目标对象
     */
    public static <S, T> T copyWithFieldMapping(S source,
                                                Class<T> targetClass,
                                                Map<String, String> fieldMapping,
                                                boolean ignoreNullSource) {
        if (source == null) return null;
        try {
            T target = targetClass.getDeclaredConstructor().newInstance();
            // 先进行普通拷贝
            BEAN_UTILS_BEAN.copyProperties(target, source);

            // 再处理字段映射
            if (fieldMapping != null && !fieldMapping.isEmpty()) {
                for (Map.Entry<String, String> e : fieldMapping.entrySet()) {
                    String sName = e.getKey();
                    String tName = e.getValue();
                    if (StringUtils.isBlank(sName) || StringUtils.isBlank(tName)) continue;

                    if (PropertyUtils.isReadable(source, sName) && PropertyUtils.isWriteable(target, tName)) {
                        Object val = PropertyUtils.getProperty(source, sName);
                        if (ignoreNullSource && val == null) continue;
                        PropertyUtils.setProperty(target, tName, val);
                    }
                }
            }
            return target;
        } catch (Exception e) {
            throw new IllegalStateException("copyWithFieldMapping failed: " + e.getMessage(), e);
        }
    }

    /* ---------- 列表复制 ---------- */

    /**
     * 拷贝集合
     *
     * @param src 源集合
     * @param targetClass 目标类型
     * @return 拷贝后的目标集合
     */
    public static <S, T> List<T> copyList(Collection<S> src, Class<T> targetClass) {
        if (src == null || src.isEmpty()) return Collections.emptyList();
        return src.stream().map(s -> copy(s, targetClass)).collect(Collectors.toList());
    }

    /**
     * 使用 Supplier 拷贝集合
     *
     * @param src 源集合
     * @param supplier 目标对象供应器
     * @return 拷贝后的目标集合
     */
    public static <S, T> List<T> copyList(Collection<S> src, Supplier<T> supplier) {
        if (src == null || src.isEmpty()) return Collections.emptyList();
        return src.stream().map(s -> {
            T t = supplier.get();
            copy(s, t);
            return t;
        }).collect(Collectors.toList());
    }

    /**
     * 忽略 null 值的集合拷贝
     *
     * @param src 源集合
     * @param supplier 目标对象供应器
     * @return 拷贝后的目标集合
     */
    public static <S, T> List<T> copyListIgnoreNull(Collection<S> src, Supplier<T> supplier) {
        if (src == null || src.isEmpty()) return Collections.emptyList();
        return src.stream().map(s -> {
            T t = supplier.get();
            copyIgnoreNull(s, t);
            return t;
        }).collect(Collectors.toList());
    }

    /**
     * 带字段映射的集合拷贝
     *
     * @param src 源集合
     * @param targetClass 目标类型
     * @param fieldMapping 字段映射关系
     * @param ignoreNullSource 是否忽略源对象中的 null 值
     * @return 拷贝后的目标集合
     */
    public static <S, T> List<T> copyListWithFieldMapping(Collection<S> src,
                                                          Class<T> targetClass,
                                                          Map<String, String> fieldMapping,
                                                          boolean ignoreNullSource) {
        if (src == null || src.isEmpty()) return Collections.emptyList();
        return src.stream()
                .map(s -> copyWithFieldMapping(s, targetClass, fieldMapping, ignoreNullSource))
                .collect(Collectors.toList());
    }


    /* ---------- 深拷贝(序列化/反序列化) ---------- */

    /**
     * 深拷贝,需外部提供序列化和反序列化函数
     *
     * @param source 源对象
     * @param serializer 序列化函数
     * @param deserializer 反序列化函数
     * @return 深拷贝后的对象
     */
    public static <T> T deepCopy(T source,
                                 Function<T, String> serializer,
                                 Function<String, T> deserializer) {
        if (source == null) return null;
        String data = serializer.apply(source);
        return deserializer.apply(data);
    }

    /* ---------- 差异检测 ---------- */

    /**
     * 比较两个对象的差异
     *
     * @param a 对象A
     * @param b 对象B
     * @return 差异映射 (字段名 -> [值A, 值B])
     */
    public static <S, T> Map<String, Object[]> diff(S a, T b) {
        Map<String, Object[]> result = new LinkedHashMap<>();
        if (a == null || b == null) return result;
        try {
            Map<String, Object> aDesc = PropertyUtils.describe(a);
            Map<String, Object> bDesc = PropertyUtils.describe(b);
            for (String key : aDesc.keySet()) {
                if ("class".equals(key)) continue;
                Object v1 = aDesc.get(key);
                Object v2 = bDesc.get(key);
                if (!Objects.equals(v1, v2)) {
                    result.put(key, new Object[]{v1, v2});
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("diff failed: " + e.getMessage(), e);
        }
        return result;
    }

    /* ---------- 合并: override 非 null 覆盖 base ---------- */

    /**
     * 合并两个对象,override 的非 null 值覆盖 base
     *
     * @param base 基础对象
     * @param override 覆盖对象
     * @return 合并后的对象(修改了base)
     */
    public static <T> T mergePreferNonNull(T base, T override) {
        if (base == null) return override;
        if (override == null) return base;
        try {
            PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(base.getClass());
            for (PropertyDescriptor desc : descriptors) {
                String name = desc.getName();
                if ("class".equals(name)) continue;

                if (PropertyUtils.isReadable(override, name) && PropertyUtils.isWriteable(base, name)) {
                    try {
                        Object ov = PropertyUtils.getProperty(override, name);
                        if (ov != null) {
                            PropertyUtils.setProperty(base, name, ov);
                        }
                    } catch (Exception ignored) {
                    }
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("mergePreferNonNull failed: " + e.getMessage(), e);
        }
        return base;
    }

    /* ---------- 安全取值 ---------- */

    /**
     * 取两个对象中第一个非 null 的
     *
     * @param a 对象A
     * @param b 对象B
     * @return 第一个非 null 对象
     */
    public static <T> T firstNonNull(T a, T b) {
        return ObjectUtils.firstNonNull(a, b);
    }

    /* ---------- Bean -> Map ---------- */

    /**
     * Bean 转 Map
     *
     * @param bean Bean 对象
     * @return 属性映射
     */
    public static Map<String, Object> toMap(Object bean) {
        if (bean == null) return Collections.emptyMap();
        try {
            Map<String, Object> map = PropertyUtils.describe(bean);
            map.remove("class");
            return map;
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new IllegalStateException("toMap failed: " + e.getMessage(), e);
        }
    }

    /* ---------- Map -> Bean ---------- */

    /**
     * Map 转 Bean
     *
     * @param map 属性映射
     * @param type Bean 类型
     * @return Bean 对象
     */
    public static <T> T fromMap(Map<String, ?> map, Class<T> type) {
        if (map == null) return null;
        try {
            T t = type.getDeclaredConstructor().newInstance();
            BEAN_UTILS_BEAN.populate(t, map);
            return t;
        } catch (Exception e) {
            throw new IllegalStateException("fromMap failed: " + e.getMessage(), e);
        }
    }

}

如果需要支持PageHelper分页对象的,可参考:gitee:BeanCopyUtilWithPageHelper

https://gitee.com/li_kun_zang/JavaUtils

特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤

免责声明:
本站文章旨在总结学习互联网技术过程中的经验与见解。任何人不得将其用于违法或违规活动!所有违规内容均由个人自行承担,与作者无关。