import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* 作用描述 util for beans
*/
public final class BeanUtil {
private static ObjectMapper INSTANCE = new ObjectMapper();
/**
* 比较两个bean的字段, 返回不同的字段及内容 格式为:
* {field:"fieldName",oldValue:"1",newValue:"2"}
*
* @param src
* 修改前对象
* @param dest
* 修改后对象
* @return
*/
public static List<Map<String, Object>> compareProperties(Object src, Object dest) {
List<Map<String, Object>> retList = new ArrayList<Map<String, Object>>();
if (src == null || dest == null) {
return retList;
}
Class<?> classSrc = src.getClass();
Class<?> classDest = dest.getClass();
Field[] destFields = classDest.getDeclaredFields();
for (Field destField : destFields) {
String name = destField.getName();
Field srcField = null;
Object oldValue = null;
Object newValue = null;
// 反射取新值
try {
destField.setAccessible(true);
newValue = destField.get(dest);
} catch (Exception e) {
// just ignore it;
continue;
}
// 反射取旧值
try {
srcField = classSrc.getDeclaredField(name);
if (srcField != null) {
srcField.setAccessible(true);
oldValue = srcField.get(src);
}
// 两个对象都有的字段, 才记录修改信息
if (!String.valueOf(newValue).equals(String.valueOf(oldValue))) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("fieldName", name);
map.put("oldValue", oldValue);
map.put("newValue", newValue);
retList.add(map);
}
} catch (Exception e1) {
// just ignore it;
}
}
return retList;
}
/**
* 复制bean的字段值
*
* @param src
* 源对象
* @param dest
* 目的对象
*/
public static void copyProperties(Object src, Object dest) {
if (src == null || dest == null) {
return;
}
Class<?> classSrc = src.getClass();
Class<?> classDest = dest.getClass();
Field[] destFields = classDest.getDeclaredFields();
// Field[] srcFields = classSrc.getDeclaredFields();
for (Field destField : destFields) {
String name = destField.getName();
Field srcField = null;
try {
srcField = classSrc.getDeclaredField(name);
} catch (Exception e2) {
continue;
}
if (srcField != null) {
srcField.setAccessible(true);
destField.setAccessible(true);
Object val = null;
try {
val = srcField.get(src);
} catch (Exception e1) {
// e1.printStackTrace();
}
if (val != null) {
try {
destField.set(dest, srcField.get(src));
} catch (Exception e) {
// e.printStackTrace();
}
}
}
}
}
/**
* 将一个 JavaBean 对象转化为一个 Map
*
* @param bean
* 要转化的JavaBean 对象
* @return 转化出来的 Map 对象
* @throws IntrospectionException
* 如果分析类属性失败
* @throws IllegalAccessException
* 如果实例化 JavaBean 失败
* @throws InvocationTargetException
* 如果调用属性的 setter 方法失败
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static Map convertBean(Object bean)
throws IntrospectionException, IllegalAccessException, InvocationTargetException {
Class type = bean.getClass();
Map returnMap = new HashMap();
BeanInfo beanInfo = Introspector.getBeanInfo(type);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; i++) {
PropertyDescriptor descriptor = propertyDescriptors[i];
String propertyName = descriptor.getName();
if (!propertyName.equals("class")) {
Method readMethod = descriptor.getReadMethod();
Object result = readMethod.invoke(bean, new Object[0]);
if (result != null) {
returnMap.put(propertyName, result);
} else {
returnMap.put(propertyName, "");
}
}
}
return returnMap;
}
public static Map<String,Object> objectToMapIgnoreNull(Object bean) throws IllegalAccessException {
Map<String, Object> map = new HashMap<>();
Field[] fields = bean.getClass().getDeclaredFields();
for (int i = 0, len = fields.length; i < len; i++) {
String varName = fields[i].getName();
if ("serialVersionUID".equals(varName)) {
continue;
}
boolean accessFlag = fields[i].isAccessible();
fields[i].setAccessible(true);
Object o = fields[i].get(bean);
if (o != null && StringUtils.isNotBlank(o.toString().trim())) {
map.put(camelToUnderline(varName), o.toString().trim());
fields[i].setAccessible(accessFlag);
}
}
return map;
}
/**
* 将一个 Map 对象转化为一个 JavaBean
*
* @param type
* 要转化的类型
* @param map
* 包含属性值的 map
* @return 转化出来的 JavaBean 对象
* @throws IntrospectionException
* 如果分析类属性失败
* @throws IllegalAccessException
* 如果实例化 JavaBean 失败
* @throws InstantiationException
* 如果实例化 JavaBean 失败
* @throws InvocationTargetException
* 如果调用属性的 setter 方法失败
*/
@SuppressWarnings("rawtypes")
public static Object convertMap(Class type, Map map)
throws IntrospectionException, IllegalAccessException, InstantiationException, InvocationTargetException {
BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性
Object obj = type.newInstance(); // 创建 JavaBean 对象
// 给 JavaBean 对象的属性赋值
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; i++) {
PropertyDescriptor descriptor = propertyDescriptors[i];
String propertyName = descriptor.getName();
if (map.containsKey(propertyName)) {
// 下面一句可以 try 起来,这样当一个属性赋值失败的时候就不会影响其他属性赋值。
Object value = map.get(propertyName);
if (Common.isEmpty(value)) {
continue;
}
if (descriptor.getPropertyType() == Integer.class || descriptor.getPropertyType() == int.class) {
value = Integer.parseInt(value.toString());
} else if (descriptor.getPropertyType() == Double.class
|| descriptor.getPropertyType() == double.class) {
value = Double.parseDouble(value.toString());
} else if (descriptor.getPropertyType() == Long.class || descriptor.getPropertyType() == long.class) {
value = Long.parseLong(value.toString());
}
Object[] args = new Object[1];
args[0] = value;
descriptor.getWriteMethod().invoke(obj, args);
}
}
return obj;
}
/**
* @param json
* 准备转换json
* @param clazz
* 集合元素类型
* @author xiaobinbin
* @return
* @description json字符串转换成对象集合
*/
@SuppressWarnings("unchecked")
public static <T> List<T> parseJsonList(String json, Class<T> clazz) {
try {
JavaType javaType = getCollectionType(ArrayList.class, clazz);
return (List<T>) INSTANCE.readValue(json, javaType);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* @param collectionClass
* 集合类
* @param elementClasses
* 集合元素类
* @author xiaobinbin
* @return
* @description 获取泛型的ColloectionType
*/
private static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
return INSTANCE.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
public static String camelToUnderline(String param) {
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (Character.isUpperCase(c) && i > 0) {
sb.append("_");
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
}