package com.tn.mdm.common.utils.bean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.*;
public class BeanUtil {
/**
* 源对象转换为目标类
*
* @param source source
* @param targetClass targetClass
* @return T
*/
public static <T> T convert(Object source, Class<T> targetClass) {
if (source == null) {
return null;
}
T target = BeanUtils.instantiateClass(targetClass);
copyProperties(source, target);
return target;
}
/**
* 复制源属性到目标属性
*
* @param source source
* @param target target
*/
public static void copyProperties(Object source, Object target) {
copyProperties(source, target, null);
}
/**
* 拷贝List集合
*
* @param sources sources
* @param targetClass targetClass
* @return T
*/
public static <T> List<T> convertList(List<?> sources, Class<T> targetClass) {
if (sources == null) {
return null;
}
List<T> targets = new ArrayList<>(sources.size());
for (Object object : sources) {
T target = BeanUtils.instantiateClass(targetClass);
copyProperties(object, target);
targets.add(target);
}
return targets;
}
/**
* 基于{@link BeanUtils}实现实例之间属性值拷贝<br>
*
* <p>增加支持枚举到枚举字符串的拷贝:
* <ul>
* <li>Enum -> String
* </li>String -> Enum
* </ul>
* </p>增加支持不同类型[属性名相同包名不同]拷贝
*
* @see BeanUtils#copyProperties(Object, Object, String[])
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static void copyProperties(Object source, Object target, String[] ignoreProperties) {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
Class<?> actualEditable = target.getClass();
PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
List<String> ignoreList = ignoreProperties != null ? Arrays.asList(ignoreProperties) : null;
for (PropertyDescriptor targetPd : targetPds) {
// 目标类所有有set方法的属性(排除过滤属性列表)
if (targetPd.getWriteMethod() != null
&& (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(),
targetPd.getName());
if (sourcePd != null && sourcePd.getReadMethod() != null) {
try {
Method readMethod = sourcePd.getReadMethod();
Object value = readMethod.invoke(source);
Method writeMethod = targetPd.getWriteMethod();
if (value != null) {
// 属性类型
Class targetPropertyClass = targetPd.getPropertyType();
Class sourcePropertyClass = sourcePd.getPropertyType();
// 判断类型是否相等=>属性名相同,类型不同(不同包名)
if (sourcePropertyClass != targetPropertyClass) {
// 枚举类型
if (targetPropertyClass.isEnum() && !sourcePropertyClass.isEnum()) {
value = Enum.valueOf(targetPropertyClass, String.valueOf(value));
} else if (!targetPropertyClass.isEnum() && sourcePropertyClass.isEnum()) {
value = String.valueOf(value);
} else {
Object _targetObject = BeanUtils.instantiateClass(targetPropertyClass);
copyProperties(value, _targetObject, null);
value = _targetObject;
}
}
}
writeMethod.invoke(target, value);
} catch (Throwable ex) {
throw new FatalBeanException("Could not copy properties from source to target", ex);
}
}
}
}
}
/**
* Bean对象转换成Map集合,过滤空值
*
* @param bean bean
* @return map
*/
public static Map<String, Object> beanToMapExcludeNull(Object bean) {
Map<String, Object> map = beanToMap(bean);
if (map != null) {
Iterator<String> keys = map.keySet().iterator();
while (keys.hasNext()) {
Object value = map.get(keys.next());
if (value == null || (value instanceof String && StringUtils.isBlank((String) value))) {
keys.remove();
}
}
}
return map;
}
/**
* Bean对象转换成Map集合
*
* @param bean bean
* @return map
*/
public static Map<String, Object> beanToMap(Object bean) {
if (bean == null) {
return null;
}
try {
BeanInfo beaninfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] descriptors = beaninfo.getPropertyDescriptors();
Map<String, Object> map = new HashMap<String, Object>(descriptors.length);
for (int i = 0; i < descriptors.length; i++) {
String name = descriptors[i].getName();
if (!"class".equals(name)) { // skip
Method method = descriptors[i].getReadMethod();
if (method != null) {
Object value = method.invoke(bean);
if (value instanceof String && StringUtils.isBlank((String) value)) {
value = null;
}
map.put(name, value);
}
}
}
return map;
} catch (Exception e) {
return Collections.emptyMap();
}
}
/**
* 过滤需要的属性值
*
* @param bean bean
* @param filterFields filterFields
* @return 值返回bean包括的属性
*/
public static Map<String, Object> beanToMap(Object bean, Set<String> filterFields) {
if (bean == null || filterFields == null) {
return null;
}
try {
BeanInfo beaninfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] descriptors = beaninfo.getPropertyDescriptors();
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < descriptors.length; i++) {
String name = descriptors[i].getName();
if (filterFields.contains(name)) {
Method method = descriptors[i].getReadMethod();
Object value = method.invoke(bean);
map.put(name, value);
}
}
return map;
} catch (Exception e) {
return Collections.emptyMap();
}
}
/**
* @param source source
* @return String[]
*/
public static String[] getNullPropertyName(Object source) {
PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(source.getClass());
List<String> fieldNames = new ArrayList<>();
for (PropertyDescriptor pd : propertyDescriptors) {
Method readMethod = pd.getReadMethod();
Object invoke = null;
try {
invoke = readMethod.invoke(source);
if (invoke == null) {
fieldNames.add(pd.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
return (String[]) fieldNames.toArray();
}
}
【工具类】BeanUtil(源对象转换为目标类、复制源属性到目标属性(拷贝时可去除id列)、拷贝List集合、Bean对象转换成Map集合,过滤空值、Bean对象转换成Map集合、过滤需要的属性值)
最新推荐文章于 2023-12-15 15:16:52 发布