All Downloads are FREE. Search and download functionalities are using the official Maven repository.

top.doudou.common.tool.bean.ConvertBeanUtils Maven / Gradle / Ivy

There is a newer version: 1.3.2
Show newest version
package top.doudou.common.tool.bean;


import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import top.doudou.base.exception.ConvertException;
import top.doudou.base.exception.CustomException;
import top.doudou.base.stream.StreamCloseUtils;
import top.doudou.common.tool.utils.FieldUtils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * bean属性的转换
 *
 * @author  傻男人<[email protected]>
 * @date 2020-03-25
 */
@Slf4j
public class ConvertBeanUtils {

    /**
     * 实体属性相互转换
     * @param entity
     * @param doClass
     * @param 
     * @return
     */
    public static  T copyProperties(E entity, Class doClass) {
        if (entity == null) {
            return null;
        } else if (doClass == null) {
            log.info("转换的class不能为null");
            throw new CustomException("转换的class不能为null");
        }
        try {
            T newInstance = doClass.newInstance();
            BeanUtils.copyProperties(entity, newInstance);
            return newInstance;
        } catch (Exception e) {
            log.info("属性转换异常!");
            throw new CustomException("bean属性转换异常");
        }
    }

    /**
     * 属性复制
     * @param source 源
     * @param target 目标
     */
    public static void copyProperties(Object source, Object target) {
        if (source == null || target == null) {
            throw new CustomException("源或者目标都不能为空");
        }
        try {
            BeanUtils.copyProperties(source, target);
        } catch (Exception e) {
            log.info("属性转换异常!");
            throw new CustomException("bean属性转换异常");
        }
    }

    /**
     * 转map
     * @param obj
     * @return 三种方式耗时最低
     */
    public static Map convertBean2Map(Object obj) {
        if (obj == null) {
            return null;
        }
        Map map = Maps.newHashMap();
        try {
            List fields = FieldUtils.getAllNoStaticFields(obj.getClass());
            for (Field field : fields) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    public static Map convertMap(Map map){
        Map result = Maps.newHashMap();
        map.forEach((key,value)->result.put(key,new Gson().toJson(value)));
        return result;
    }


    public static T convert(String json, Class target, Charset charset){
        if(StringUtils.isBlank(json)){
            return null;
        }
        T t = null;
        try {
            ObjectMapper mapper = new ObjectMapper();
            //当属性的值为空(null或者"")时,不进行序列化,可以减少数据传输
            mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
            //设置日期格式
            mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            t = mapper.readValue(new String(json.getBytes(charset), charset), target);
            return t;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return t;
    }


    /**
     * 转map
     * @param obj
     * @return 三种方式最耗时
     */
    public static Map objToMap(Object obj) {
        Gson gson = new Gson();
        return gson.fromJson(gson.toJson(obj),Map.class);
    }

    /**
     * 实体类转map
     * @param obj
     * @return
     */
    public static Map convertBeanToMap(Object obj) {
        if (obj == null) {
            return null;
        }
        Map map = Maps.newHashMap();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (!key.equals("serialVersionUID") && !key.equals("class")) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
                    if(null==value){
                        map.put(key,"");
                    }else{
                        map.put(key,value);
                    }
                }
            }
        } catch (Exception e) {
            log.error("convertBean2Map Error {}" ,e);
        }
        return map;
    }

    /**
     * Map转实体类
     * @param map
     * @param beanClass
     * @return
     */
    public static  T mapToObj(Map map, Class beanClass) {
        if (map == null) return null;
        try {
            T t = beanClass.newInstance();
            BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                Method setter = property.getWriteMethod();
                if (setter != null) {
                    setter.invoke(t, map.get(property.getName()));
                }
            }
            return t;
        }catch (Exception e){
            e.printStackTrace();
            throw new CustomException("bean属性转换异常");
        }
    }

    /**
     * bean属性复制(bean中包含list)
     */
    public static  T copyPropertiesContainList(Object source, Class doClass) {
        if (source == null) {
            return null;
        } else if (doClass == null) {
            log.info("转换的class不能为null");
            throw new CustomException("转换的class不能为null");
        }

        Field[] sourFields = source.getClass().getDeclaredFields();

        // 将 source 的属性对象为 value,属性名为 key 封装为 map
        Map sourFieldMap = Maps.newHashMap();
        Arrays.stream(sourFields).forEach(sourField -> sourFieldMap.put(sourField.getName(), sourField));
        try {
            T target = doClass.newInstance();
            Field[] tarFields = target.getClass().getDeclaredFields();
            for (Field tarField : tarFields) {
                // 从 sourFieldMap 中通过 fieldName 取值,若能取出表示存在相同的属性名
                Field sourField = sourFieldMap.get(tarField.getName());
                if (sourField == null || "serialVersionUID".equals(sourField.getName())) {
                    continue;
                }
                Class tarGenericClass = getGenericClass(tarField);
                Class sourGenericClass = getGenericClass(sourField);

                // 获取属性声明的类型 Class 对象
                Class sourType = sourField.getType();
                Class tarType = tarField.getType();

                sourField.setAccessible(true);
                tarField.setAccessible(true);

                // 若不是 List 或其父接口类型,为 null
                if (tarGenericClass == null && sourGenericClass == null) {
                    // target 属性类型是 source 属性类型的子类或子接口
                    if (sourType.isAssignableFrom(tarType)) {
                        tarField.set(target, sourField.get(source));
                    }
                } else if (tarGenericClass != null && sourGenericClass != null) {
                    // Iterable 是 List 最顶层接口,在 sourGenericClass 中判断是声明类型是 List 或其父接口
                    Iterable sourList = (Iterable) sourField.get(source);
                    if (sourList == null) {
                        continue;
                    }
                    // 该集合用于添加 target 拷贝的对象
                    List tarList = Lists.newArrayList();
                    for (Object sourObj : sourList) {
                        tarList.add(copyPropertiesContainList(sourObj, tarGenericClass.newInstance().getClass()));
                    }
                    tarField.set(target, tarList);
                }
            }
            return target;
        } catch (Exception e) {
            log.info("复制属性出错");
            throw new CustomException("bean属性转换异常");
        }
    }

    /**
     * 获取属性类型中的泛型类型,获取泛型的过程适用于其他类型,但是本方法仅适用于 List 集合,
     * 并且只有一个泛型的情况,若有需求后续增加功能。
     *
     * @param field
     * @return
     * @throws Exception
     */
    private static Class getGenericClass(Field field) throws Exception {
        // 获取属性声明的类型 Class 对象
        Class type = field.getType();
        // 判断该 type 是否是 List 或其父接口
        if (type.isAssignableFrom(List.class)) {
            // 获取该属性声明的类型(Type 接口),getType():是获取属性声明的类型 Class 对象
            Type genericType = field.getGenericType();
            if (genericType == null) {
                return null;
            }
            // 判断 geneicType 是否是参数化类型,即明确指定泛型的类型,如:java.util.List
            if (genericType instanceof ParameterizedType) {
                //因为 genericType 是 ParameterizedType 的实例,故可以强转
                ParameterizedType pt = (ParameterizedType) genericType;
                // 获取泛型的类型数组
                Type[] genericArgs = pt.getActualTypeArguments();
                // 当泛型类型大于 1 个时,抛出异常
                if (genericArgs.length > 1) {
                    throw new Exception(genericType + "  " + field.getName() + ": 泛型不只一个无法赋值");
                }
                // 当只有一个泛型类型时,获取泛型类型
                return (Class) genericArgs[0];
            }
        }
        return null;
    }

    /**
     * 将Java对象序列化为二进制数据
     *
     * @param obj 需要序列化的的对象
     * @return 二进制数据
     */
    public static byte[] objectToByte(Object obj) {
        ByteArrayOutputStream bo = null;
        ObjectOutputStream oo = null;
        try {
            bo = new ByteArrayOutputStream();
            oo = new ObjectOutputStream(bo);
            oo.writeObject(obj);
            byte[] bytes = bo.toByteArray();
            return bytes;
        } catch (Exception e) {
            log.info(" 对象序列化出现问题,出现问题的原因为 {}", e.getMessage());
            throw new ConvertException("convert to byte[] error");
        } finally {
            StreamCloseUtils.close(bo);
            StreamCloseUtils.close(oo);
        }
    }

    /**
     * 将序列化化后的二进制数据反序列化为对象
     *
     * @param bytes 序列化化后的二进制数据
     * @return 对象
     */
    public static Object byteToObject(byte[] bytes) {
        ByteArrayInputStream bi = null;
        ObjectInputStream oi = null;
        try {
            bi = new ByteArrayInputStream(bytes);
            oi = new ObjectInputStream(bi);
            return oi.readObject();
        } catch (Exception e) {
            log.info("对象反序列化出现问题,出现问题的原因为 {}", e.getMessage());
            throw new ConvertException("byte[] convert to Object error");
        }finally {
            StreamCloseUtils.close(bi);
            StreamCloseUtils.close(oi);
        }
    }

    /**
     * 将序列化化后的二进制数据反序列化为对象
     *
     * @param target     希望序列化成的数据类型,不能为空
     *
     * @param bytes 序列化化后的二进制数据
     * @return 对象
     */
    @SuppressWarnings("unchecked")
    public static  T byteToObject(Class target, byte[] bytes) {
        return (T)byteToObject(bytes);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy