/**
* @author : tangjiabin
* @date 2018/5/24 13:16
*/
public class BeanUtil {
private static final Logger LOG = LoggerFactory.getLogger(BeanUtil.class);
/**
*默认格式化器缓存
*/
private static Map formatterMap = new HashMap();
/**
*转换器
*/
private static Map converterMap = new HashMap();
static {
// // 默认Double精确到小数点后两位
// formatterMap.put(Double.class, new AmountFormatter()); 默认使用Apache的转换器
ConvertUtilsBean convertUtilsBean = BeanUtilsBean.getInstance().getConvertUtils();
try {
Field field = ConvertUtilsBean.class.getDeclaredField("converters");
if (!field.isAccessible()) {
field.setAccessible(true);
}
Map beanUtilsMap =
(Map) field.get(convertUtilsBean);
converterMap.putAll(beanUtilsMap);
} catch (Exception e) {
LOG.error("获取类ConvertUtilsBean的属性converters异常!", e);
}
}
/**
* 注册转换器
*
* @param converter
* @param targetType
*/
public void register(Converter converter, Class targetType) {
converterMap.put(targetType, converter);
}
/**
* 数据转换
*
* @param source
* 源数据
*
* @param targetType
* 目标类型
*
* @return
*/
public static Object convert(Object source, Class targetType) {
Object result = source;
if (null == targetType) {
return result;
}
Converter converter = converterMap.get(targetType);
if (null != converter) {
result = converter.convert(targetType, source);
}
return result;
}
/**
* 对象属性拷贝(浅)
*
* @param source
* 源对象
*
* @param target
* 目标对象
*/
public static void copyProperties(Object source, Object target) {
BeanUtils.copyProperties(source,target);
}
/**
* 对象属性拷贝(使用转换器)
*
* @param source
* 源对象
*
* @param target
* 目标对象
*
*
* @param formattersByClass
* 按类格式化器
*
* @param formattersByClass
* 按名称格式化器
*
*
*/
public static void copyProperties(Object source, Object target,
Map formattersByClass, Map formattersByName,
Map convertersByClass, Map convertersByName) {
copyProperties(source, target, null, formattersByClass, formattersByName,
convertersByClass, convertersByName);
}
/**
* 对象属性拷贝
*
* @param source
* 源对象
*
* @param target
* 目标对象
*
* @param isDeep
* 是否深拷贝
*/
public static void copyProperties(Object source, Object target, boolean isDeep) {
copyProperties(source, target, null, isDeep);
}
/**
* 对象属性拷贝
*
* @param source
* 源对象
*
* @param target
* 目标对象
*
* @param ignoreProperties
* 排除属性
*
* @param isDeep
* 是否深拷贝
*
*/
public static void copyProperties(Object source, Object target, String[] ignoreProperties,
boolean isDeep) {
copyProperties(source, target, ignoreProperties, null, null, null, null, false);
}
/**
* 对象属性拷贝(浅)
*
* @param source
* 源对象
*
* @param target
* 目标对象
*
* @param ignoreProperties
* 排除属性
*
*/
public static void copyProperties(Object source, Object target, String[] ignoreProperties) {
copyProperties(source, target, ignoreProperties, null);
}
/**
* 对象属性拷贝(使用转换器)
*
* @param source
* 源对象
*
* @param target
* 目标对象
*
* @param ignoreProperties
* 排除属性
*
*
*/
public static void copyProperties(Object source, Object target, String[] ignoreProperties,
Map formattersByClass) {
copyProperties(source, target, ignoreProperties, formattersByClass, null, null, null);
}
/**
* 对象属性拷贝(使用转换器)
*
* @param source
* 源对象
*
* @param target
* 目标对象
*
* @param ignoreProperties
* 排除属性
*
* @param formattersByClass
* 按类格式化器
*
* @param formattersByClass
* 按名称格式化器
*
*/
public static void copyProperties(Object source, Object target, String[] ignoreProperties,
Map formattersByClass, Map formattersByName,
Map convertersByClass, Map convertersByName) {
copyProperties(source, target, ignoreProperties, formattersByClass, formattersByName,
convertersByClass, convertersByName, false);
}
/**
* 对象属性拷贝(使用转换器)
*
* @param source
* 源对象
*
* @param target
* 目标对象
*
* @param ignoreProperties
* 排除属性
*
*
* @param isDeep
* 是否深拷贝
*/
public static void copyProperties(Object source, Object target, String[] ignoreProperties,
Map formattersByClass, Map formattersByName,
Map convertersByClass, Map convertersByName,
boolean isDeep) {
if (null == source || null == target) {
return;
}
Class> actualEditable = target.getClass();
PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(actualEditable);
List ignoreList =
(ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
for (PropertyDescriptor pd : pds) {
Object value = null;
String name = pd.getName();
boolean bo = "class".equals(name) || (ignoreProperties != null && ignoreList.contains(name));
if (bo) {
continue;
}
if (source instanceof Map) {
value = ((Map) source).get(name);
} else {
PropertyDescriptor sourcePd =
BeanUtils.getPropertyDescriptor(source.getClass(), name);
if (null == sourcePd) {
continue;
}
Method readMethod = sourcePd.getReadMethod();
if (null != readMethod) {
try {
value = readMethod.invoke(source, null);
} catch (Exception e) {
LOG.error(
"Could not get property:" + name + " from class:"
+ source.getClass(), e);
continue;
}
} else {
Field sourceField = null;
try {
sourceField = source.getClass().getDeclaredField(name);
} catch (Exception e) {
LOG.error(
"Could not get property:" + name + " from class:"
+ source.getClass(), e);
continue;
}
if (!sourceField.isAccessible()) {
sourceField.setAccessible(true);
}
try {
value = sourceField.get(source);
} catch (Exception e) {
LOG.error(
"Could not get property:" + name + " from class:"
+ source.getClass(), e);
continue;
}
}
}
// 设值
copyProperty(target, name, value, formattersByClass, formattersByName,
convertersByClass, convertersByName, isDeep);
}
}
/**
* 对目标对象设值
*
* @param target
* 目标对象
*
* @param name
* 目标属性
*
* @param value
* 目标值
*
*/
public static void copyProperty(Object target, String name, Object value) {
copyProperty(target, name, value, null, null, null, null, false);
}
/**
* 对目标对象设值
*
* @param target
* 目标对象
*
* @param name
* 目标属性名
*
* @param value
* 目标值
*
* @param formattersByClass
* 根据类型格式化器
*
* @param formattersByName
* 根据名称格式化器
*
* @param isDeep
* 是否深拷贝
*
*/
public static void copyProperty(Object target, String name, Object value,
Map formattersByClass, Map formattersByName,
Map convertersByClass, Map convertersByName,
boolean isDeep) {
String clazz = "class";
if (null == target || clazz.equals(name)) {
return;
}
Class targetType = Object.class;
if (target instanceof Map) {
if (null != value) {
Type[] types = target.getClass().getGenericInterfaces();
if (null != types && types.length > 0) {
if (types[0] instanceof ParameterizedType) {
// 执行强制类型转换
ParameterizedType parameterizedType = (ParameterizedType) types[0];
// 获取泛型类型的泛型参数
Type[] argTypes = parameterizedType.getActualTypeArguments();
if (null != argTypes && argTypes.length > 1) {
targetType = argTypes[1].getClass();
}
}
}
// 数据转换
value =
convertValue(name, value, formattersByClass, formattersByName,
convertersByClass, convertersByName, isDeep, value.getClass(),
targetType);
}
((Map) target).put(name, value);
} else {
PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(target.getClass(), name);
if (null == pd) {
return;
}
if (null != value) {
targetType = pd.getPropertyType();
// 数据转换
value =
convertValue(name, value, formattersByClass, formattersByName,
convertersByClass, convertersByName, isDeep, value.getClass(),
targetType);
}
Method writeMethod = pd.getWriteMethod();
if (null != writeMethod) {
try {
writeMethod.invoke(target, value);
} catch (Exception e) {
LOG.error("Could not copy propertie=" + name + ",value=" + value
+ " to target ", e);
}
} else {
Field field = null;
try {
field = target.getClass().getDeclaredField(name);
} catch (NoSuchFieldException e) {
LOG.error("class:" + target.getClass() + " has not field:" + name, e);
return;
}
boolean bo = !Modifier.isFinal(field.getModifiers())|| (Modifier.isFinal(field.getModifiers()) && null == value);
if (bo) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
try {
field.set(target, value);
} catch (Exception e) {
LOG.error("Could not copy properties from source to target", e);
}
}
}
}
}
/**
* 数据转换
*
* @param name
* 目标属性名
*
* @param value
* 目标值
*
* @param formattersByClass
* 根据类型格式化器
*
* @param formattersByName
* 根据名称格式化器
*
* @param convertersByClass
* 根据类型转换器
*
* @param convertersByName
* 根据名称转换器
*
* @param isDeep
* 是否深拷贝
*
* @param srcType
* 原类型
*
*
*
* @param targetType
* @return
*/
private static Object convertValue(String name, Object value,
Map formattersByClass, Map formattersByName,
Map convertersByClass, Map convertersByName,
boolean isDeep, Class srcType, Class targetType) {
if (null != value) {
// 根据类型格式化器
Formatter formatterByClass = null;
// 优先取传入的格式化器
if (null != formattersByClass && !formattersByClass.isEmpty()) {
formatterByClass = formattersByClass.get(value.getClass());
}
if (null == formatterByClass) {
formatterByClass = formatterMap.get(value.getClass());
}
if (null != formatterByClass) {
value = formatterByClass.format(value);
}
// 根据名称格式化器
Formatter formatterByName = null;
// 优先取传入的格式化器
if (null != formattersByName && !formattersByName.isEmpty()) {
formatterByName = formattersByName.get(name);
}
if (null != formatterByName) {
value = formatterByName.format(value);
}
// 数据类型转换
if (!srcType.equals(targetType) && !targetType.isAssignableFrom(srcType)) {
// 根据类型转换器
Converter converterByClass = null;
// 优先取传入的格式化器
if (null != convertersByClass && !convertersByClass.isEmpty()) {
converterByClass = convertersByClass.get(targetType);
}
if (null != converterByClass) {
value = converterByClass.convert(targetType, value);
}
// 根据名称转换器
Converter converterByName = null;
// 优先取传入的格式化器
if (null != convertersByName && !convertersByName.isEmpty()) {
converterByName = convertersByName.get(name);
}
if (null != converterByName) {
value = converterByName.convert(targetType, value);
}
if (null == converterByClass && null == formatterByName) {
value = convert(value, targetType);
}
}
if (isDeep) {
value = deepClone(value);
}
}
return value;
}
/**
* 克隆对象(浅)
*
* @param source
* @return
*/
public static Object clone(Object source) {
return clone(source, false);
}
/**
* 克隆对象(深)
*
* @param source
* @return
*/
public static Object deepClone(Object source) {
return clone(source, true);
}
/**
* 克隆对象(浅)
*
* @param source
* 源对象
*
* @param isDeep
* 是否深拷贝
*
* @return
*/
public static Object clone(Object source, boolean isDeep) {
Object cloneObj = null;
if (null != source) {
Class extends Object> clazz = source.getClass();
if (clazz.isInterface()) {
return cloneObj;
}
if (!ObjectUtil.isBasicDataType(clazz)) {
if (Collection.class.isAssignableFrom(clazz)) {
try {
Collection collection = (Collection) source;
Collection cloneCol = newCollection(collection);
if (null != cloneCol) {
Iterator it = collection.iterator();
if (it.hasNext()) {
cloneCol.add(clone(it.next(), isDeep));
}
cloneObj = cloneCol;
}
} catch (Exception e) {
LOG.error("类" + clazz + "拷贝异常!", e);
}
} else if (Map.class.isAssignableFrom(clazz)) {
try {
Constructor> constructor = clazz.getDeclaredConstructor();
if (null != constructor) {
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
Map cloneMap = (Map) constructor.newInstance();
Map map = (Map) source;
for (Object key : map.keySet()) {
cloneMap.put(clone(key, isDeep), clone(map.get(key), isDeep));
}
cloneObj = cloneMap;
}
} catch (Exception e) {
LOG.error("类" + clazz + "拷贝异常!", e);
}
} else if (clazz.isArray()) {
Object[] sourceArray = (Object[]) source;
cloneObj = Array.newInstance(clazz.getComponentType(), sourceArray.length);
Object[] cloneArray = (Object[]) cloneObj;
for (int i = 0; i < cloneArray.length; i++) {
cloneArray[i] = clone(sourceArray[i], isDeep);
}
} else if (String.class.equals(clazz)) {
cloneObj = source;
} else {
if (isDeep) {
try {
cloneObj = JsonUtil.toBean(JsonUtil.toJson(source), clazz);
} catch (Exception e) {
LOG.error("类" + clazz + "json转换异常!", e);
}
} else if (source instanceof Cloneable) {
try {
Method method = clazz.getMethod("clone", null);
cloneObj = method.invoke(source, null);
} catch (Exception e) {
LOG.error("类" + clazz + "拷贝异常!", e);
}
} else {
try {
try {
Constructor> constructor = clazz.getDeclaredConstructor();
if (null != constructor) {
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
cloneObj = constructor.newInstance();
}
} catch (Exception e) {
LOG.error("类" + clazz + "调用默认构造器异常!", e);
}
if (null == cloneObj) {
cloneObj = JsonUtil.toBean(JsonUtil.toJson(source), clazz);
}
copyProperties(source, cloneObj);
} catch (Exception e) {
LOG.error("类" + clazz + "拷贝异常!", e);
}
}
}
} else {
cloneObj = source;
}
}
return cloneObj;
}
/**
* 实例化一个对象
*
* @param clazz
* 类
*
*
* @return
*/
public static Object newInstance(Class> clazz, Object... args) {
Object result = null;
try {
Constructor> constructor = null;
if (null == args || args.length == 0) {
constructor = clazz.getDeclaredConstructor();
} else {
Class>[] argClasses = new Class>[args.length];
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
if (null == arg) {
argClasses[i] = String.class;
} else {
argClasses[i] = arg.getClass();
}
}
constructor = clazz.getDeclaredConstructor(argClasses);
}
if (null != constructor) {
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
result = constructor.newInstance(args);
}
} catch (Exception e) {
LOG.error("类" + clazz + "调用构造器异常!", e);
}
return result;
}
/**
* 新建一个空的集合
*
* @param collection
* @return
* @throws NoSuchMethodException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static Collection> newCollection(Collection> collection)
throws NoSuchMethodException, InstantiationException, IllegalAccessException,
InvocationTargetException {
Collection> resultCol = null;
Class extends Object> clazz = collection.getClass();
if (clazz.isInterface()) {
return resultCol;
}
Constructor> constructor = clazz.getDeclaredConstructor(Integer.TYPE);
if (null != constructor) {
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
resultCol = (Collection>) constructor.newInstance(collection.size());
} else {
constructor = clazz.getDeclaredConstructor();
if (null != constructor) {
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
resultCol = (Collection>) constructor.newInstance();
}
}
return resultCol;
}
/**
* 序列化对象,然后再取出
*
* @param source
* @return
*/
public static Object serialize(Object source) {
ByteArrayOutputStream memoryBuffer = new ByteArrayOutputStream();
ObjectOutputStream out = null;
ObjectInputStream in = null;
Object target = null;
try {
out = new ObjectOutputStream(memoryBuffer);
out.writeObject(source);
out.flush();
in = new ObjectInputStream(new ByteArrayInputStream(memoryBuffer.toByteArray()));
target = in.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (out != null) {
try {
out.close();
out = null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (in != null){
try {
in.close();
in = null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
return target;
}
/**
* 获取对象的静态属性值
*
*
* @param propertyName
* 属性名称
*
* @return
*/
public static Object getStaticPropertyValue(Class> clazz, String propertyName) {
Object value = null;
if (null == clazz || StringUtils.isBlank(propertyName)) {
return value;
}
PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, propertyName);
Method readMethod = null;
if (null != pd) {
readMethod = pd.getReadMethod();
}
if (null != readMethod) {
try {
if (!readMethod.isAccessible()) {
readMethod.setAccessible(true);
}
value = readMethod.invoke(clazz, null);
} catch (Exception e) {
LOG.error("类" + clazz + "调用方法" + readMethod.getName() + "异常!", e);
}
} else {
Field[] fields = clazz.getDeclaredFields();
if (null != fields && fields.length > 0) {
for (Field field : fields) {
if (propertyName.equals(field.getName())) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
try {
value = field.get(clazz);
} catch (IllegalArgumentException e) {
LOG.error("属性:" + field + "参数非法!", e);
} catch (IllegalAccessException e) {
LOG.error("属性:" + field + "访问非法!", e);
}
break;
}
}
}
}
return value;
}
/**
* 获取对象的属性值
*
* @param obj
* 目标对象
*
* @param propertyName
* 属性名称
*
* @return
*/
public static Object getPropertyValue(Object obj, String propertyName) {
Object value = null;
if (null == obj || StringUtils.isBlank(propertyName)) {
return value;
}
String str = ".";
if (propertyName.indexOf(str) > -1) {
String[] propertyNames = propertyName.split("\\.");
for (String name : propertyNames) {
obj = getPropertyValue(obj, name);
}
value = obj;
} else {
Class extends Object> clazz = obj.getClass();
PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, propertyName);
Method readMethod = null;
if (null != pd) {
readMethod = pd.getReadMethod();
}
if (null != readMethod) {
try {
if (!readMethod.isAccessible()) {
readMethod.setAccessible(true);
}
value = readMethod.invoke(obj, null);
} catch (Exception e) {
LOG.error("类" + clazz + "调用方法" + readMethod.getName() + "异常!", e);
}
} else {
Field[] fields = clazz.getDeclaredFields();
if (null != fields && fields.length > 0) {
for (Field field : fields) {
if (propertyName.equals(field.getName())) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
try {
value = field.get(obj);
} catch (IllegalArgumentException e) {
LOG.error("属性:" + field + "参数非法!", e);
} catch (IllegalAccessException e) {
LOG.error("属性:" + field + "访问非法!", e);
}
break;
}
}
}
}
}
return value;
}
/**
* 获取类的属性
*
* @param clazz
* @return
*/
public static String[] getPropertyNames(Class clazz) {
String[] names = null;
PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(clazz);
if (null != pds && pds.length > 0) {
List list = new ArrayList();
names = new String[pds.length];
for (int i = 0; i < pds.length; i++) {
String name = pds[i].getName();
if ("class".equals(name)) {
continue;
}
list.add(name);
}
names = list.toArray(new String[list.size()]);
}
return names;
}
/**
* 对象转换成Map
*
* @param obj
* @return
*/
public static Map toMap(Object obj) {
Map map = Collections.emptyMap();
if (null == obj) {
return map;
}
if (obj instanceof Map) {
return (Map) obj;
}
try {
map = org.apache.commons.beanutils.BeanUtils.describe(obj);
} catch (Exception e) {
LOG.error("对象:" + obj + "转换Map异常!", e);
}
String clazz = "class";
if (null != map && map.containsKey(clazz)) {
map.remove(clazz);
}
return map;
}
/**
* 判断类是否基本数据类型与封装类
* @param clazz
* @return
*/
public static boolean isPrimitive(Class> clazz) {
if (null == clazz) {
return false;
}
if (clazz.isPrimitive() || String.class.isAssignableFrom(clazz)) {
return true;
}
Object type = getStaticPropertyValue(clazz, "TYPE");
if (null != type && type instanceof Class) {
Class> classType = (Class>) type;
if (classType.isPrimitive()) {
return true;
}
}
return false;
}
/**
* 判断对象是否基本数据类型与封装类
* @param obj
* @return
*/
public static boolean isPrimitive(Object obj) {
if (null == obj) {
return false;
}
if (obj.getClass().isPrimitive() || obj instanceof String) {
return true;
}
Object type = getPropertyValue(obj, "TYPE");
if (null != type && type instanceof Class) {
Class> classType = (Class>) type;
if (classType.isPrimitive()) {
return true;
}
}
return false;
}
/**
* 比较相同类型的对象的不同属性
* @param one
* @param another
* @return
*/
public static List compare(Object one, Object another) {
List resultList = Collections.emptyList();
Class extends Object> clazz = one.getClass();
if (null == one || null == another || !clazz.equals(another.getClass())) {
return resultList;
}
resultList = new ArrayList();
String[] names = getPropertyNames(clazz);
for (String name : names) {
Object value1 = getPropertyValue(one, name);
Object value2 = getPropertyValue(another, name);
boolean bo = (null != value1 && (null == value2 || !value1.equals(value2)))|| (null != value2 && (null == value1 || !value2.equals(value1)));
if (bo) {
resultList.add(name);
}
}
return resultList;
}
private interface Formatter {
/**
* 格式化
* @param source
* @return : java.lang.Object
* @author : tangjiabin
* @date 2018/5/24 14:03
*/
public Object format(Object source);
}
private class AmountFormatter implements Formatter {
private static final String DEFAULT_FORMAT = "0.00";
/**
*格式
*/
private String format = DEFAULT_FORMAT;
/**
* 时间转换
*/
@Override
public Object format(Object source) {
Object dest = null;
DecimalFormat df = new DecimalFormat(format);
if (null != source) {
dest = df.format(source);
}
return dest;
}
}
}