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博客搜索:标题关键字。以获取最新全部资料 ❤
免责声明: 本站文章旨在总结学习互联网技术过程中的经验与见解。任何人不得将其用于违法或违规活动!所有违规内容均由个人自行承担,与作者无关。
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤
免责声明: 本站文章旨在总结学习互联网技术过程中的经验与见解。任何人不得将其用于违法或违规活动!所有违规内容均由个人自行承担,与作者无关。

评论(0)