java常用反射调用工具类

package com.alibaba.polystar.common.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.alibaba.fastjson.util.TypeUtils;
import com.alibaba.polystar.common.annocation.TencentAnnotation;
import com.alibaba.polystar.common.dto.CampaignDTO;
import com.alibaba.polystar.common.util.log.LoggerUtil;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

/**
 * @author hezhenyuan
 */
public class BeanUtil {

    private static final String JSON_SPLIT = ".";

    private static final String JSON_ARRAY_START_WITH = "[";

    /**
     * 获取目标class的注解的name结合
     *
     * @param clazz           目标class
     * @param annotationClass 注解的class
     * @return 所有注解的name结合
     */
    public static List<String> getAnnotationNames(Class<?> clazz, Class<?> annotationClass) {

        final Field[] fields = getAllFields(clazz);
        if (fields.length < 1) {
            return null;
        }
        List<String> filedNames = new ArrayList<>(fields.length);
        Arrays.asList(fields).forEach(f -> {
            Annotation[] annotations = f.getDeclaredAnnotations();
            if (annotations.length < 1) {
                return;
            }
            for (int i = 0; i < annotations.length; i++) {
                Annotation annotation = annotations[i];
                if (annotation.annotationType().equals(annotationClass)) {
                    String name = JSONObject.parseObject(JSONObject.toJSONString(annotation)).getString("name");
                    if (name.contains(JSON_SPLIT)) {
                        String[] names = StringUtils.split(name, JSON_SPLIT);
                        if (!filedNames.contains(names[0])) {
                            filedNames.add(names[0]);
                        }
                    } else {
                        filedNames.add(name);
                    }
                }
            }
        });
        return filedNames;
    }

    /**
     * 获取二个类的属性差集
     *
     * @param obj   目标对象
     * @param clazz 做差值的类
     * @return 二个类中不同的数据差集
     */
    public static JSONObject getDiffValues(Object obj, Class clazz) {
        List<String> diffFiledNames = BeanUtil.diff(obj.getClass(), clazz);
        return BeanUtil.getJSONObject(obj, diffFiledNames);
    }

    /**
     * 计算在 class1中存在,在class2中不存在的属性
     *
     * @param clazz1 类1
     * @param clazz2 类2
     * @return 属性名称列表差集
     */
    public static List<String> diff(Class clazz1, Class clazz2) {

        final Field[] field1 = getAllFields(clazz1);
        if (field1 == null || field1.length < 1) {
            return null;
        }
        final Field[] field2 = getAllFields(clazz2);

        List<String> filedNames1 = Arrays.stream(field1).map(Field::getName).collect(Collectors.toList());
        List<String> filedNames2 = Arrays.stream(field2).map(Field::getName).collect(Collectors.toList());

        filedNames1.removeAll(filedNames2);

        return filedNames1;
    }

    public static JSONObject getJSONObject(Object obj, List<String> fieldNames) {

        if (CollectionUtils.isEmpty(fieldNames)) {
            return null;
        }
        JSONObject jsonObject = new JSONObject();
        //得到class
        final Class<?> c = obj.getClass();
        fieldNames.forEach(fieldName -> {
            try {
                Field field = c.getDeclaredField(fieldName);
                field.setAccessible(true);
                Object value = field.get(obj);
                if (value == null) {
                    return;
                }
                if (field.getType().isPrimitive()) {
                    jsonObject.put(fieldName, value);
                } else if (isBaseType(value)) {
                    jsonObject.put(fieldName, value);
                } else {
                    jsonObject.put(fieldName, JSONObject.toJSONString(value));
                }
            } catch (IllegalAccessException | NoSuchFieldException e) {
                throw new RuntimeException(e);
            }
        });
        return jsonObject;
    }

    /**
     * 是否是基础类型
     *
     * @param obj java对象
     * @return 是否是基础类型
     */
    public static boolean isBaseType(Object obj) {
        return obj instanceof Integer || obj instanceof Double || obj instanceof Float || obj instanceof String
            || obj instanceof Long || obj instanceof Boolean || obj instanceof Date;
    }

    /**
     * 讲包下面的enum转map
     *
     * @param packageDir 目标路径
     * @return 路径下的所有枚举转map
     */
    public static Map<String, List<Map<String, String>>> enumToMap(String packageDir) {
        List<Class> classList = ClassUtils.classList(packageDir);
        Map<String, List<Map<String, String>>> result = new HashMap<>(classList.size());
        classList.stream().filter(clazz -> clazz.isEnum()).forEach(clazz -> {
            List<Map<String, String>> mapList = Lists.newArrayList();
            result.put(clazz.getSimpleName(), mapList);
            try {
                Method method = clazz.getMethod("values", null);
                Object[] invokes = (Object[])method.invoke(null, (Object[])null);
                for (Object obj : invokes) {
                    Method desc = BeanUtils.findMethod(clazz, "getDesc");
                    Method code = BeanUtils.findMethod(clazz, "getCode");
                    Enum e = (Enum)obj;
                    Map<String, String> map = new HashMap<>(2);
                    if (code.invoke(obj) == null) {
                        LoggerUtil.warn(LoggerUtil.commonErrorLogger, "enumToMap is null,obj=", obj);
                    } else {
                        map.put("key", code.invoke(obj).toString());
                    }
                    if (desc != null) {
                        map.put("value", desc.invoke(obj).toString());
                    } else {
                        map.put("value", e.name());
                    }
                    mapList.add(map);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        return result;
    }

    public static <T> T deserialization(JSONObject jsonObject, Class<T> clazz, Class annotationClass) {
        final Field[] fields = getAllFields(clazz);
        try {
            T obj = clazz.newInstance();
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                final Annotation annotation = field.getDeclaredAnnotation(annotationClass);
                if (annotation == null) {
                    continue;
                }
                final String key = JSONObject.parseObject(JSONObject.toJSONString(annotation)).getString("name");
                final Object jsonValue = JSONPath.read(jsonObject.toJSONString(), key);
                if (jsonObject == null) {
                    continue;
                }
                field.setAccessible(true);
                //如果不是List类型
                if (!(jsonValue instanceof JSONArray)) {
                    final Object value = TypeUtils.castToJavaBean(jsonValue, field.getType());
                    field.set(obj, value);
                    continue;
                }

                if (annotation instanceof TencentAnnotation) {
                    TencentAnnotation tencentAnnotation = (TencentAnnotation)annotation;
                    final String split = tencentAnnotation.split();
                    field.set(obj, StringUtils.join((JSONArray)jsonValue, split));
                    continue;
                }
            }
            return obj;
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public static JSONObject toJSON(Object obj, Class annotationClass) {
        final Field[] fields = getAllFields(obj.getClass());
        JSONObject jsonObject = new JSONObject();
        Arrays.stream(fields).forEach(
            field -> {
                final Annotation annotation = field.getDeclaredAnnotation(annotationClass);
                if (annotation == null) {
                    return;
                }
                field.setAccessible(true);
                try {
                    Object value = field.get(obj);
                    if (value == null) {
                        return;
                    }
                    if ((value instanceof String) && StringUtils.isEmpty((String)value)) {
                        return;
                    }
                    final String key = JSONObject.parseObject(JSONObject.toJSONString(annotation)).getString("name");
                    final String split = JSONObject.parseObject(JSONObject.toJSONString(annotation)).getString("split");

                    if (!StringUtils.isEmpty(split)) {
                        value = ((String)value).split(split);
                    }
                    if (!key.contains(JSON_SPLIT)) {
                        jsonObject.put(key, value);
                    } else {
                        String[] splits = StringUtils.split(key, JSON_SPLIT);
                        String key0 = splits[0];
                        String key1 = splits[1];

                        if (jsonObject.containsKey(key0)) {
                            jsonObject.getJSONObject(key0).put(key1, value);
                        } else {
                            Object finalValue = value;
                            jsonObject.put(key0, new HashMap<String, Object>(2) {
                                {
                                    put(key1, finalValue);
                                }
                            });
                        }
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        );
        return jsonObject;
    }

    public static <T> List<T> batchDeserialization(JSONArray jsonArray, Class<T> clazz, Class<?> annotationClass) {
        if (jsonArray == null || jsonArray.size() < 1) {
            return null;
        }
        List<T> list = new ArrayList<>(jsonArray.size());
        for (int i = 0; i < jsonArray.size(); i++) {
            T obj = BeanUtil.deserialization(jsonArray.getJSONObject(i), clazz, annotationClass);
            list.add(obj);
        }
        return list;
    }

    /**
     * 讲do的properties重新放入DTO
     *
     * @param jsonObject properties
     * @param obj        DTO
     */
    public static void reSetProperties(JSONObject jsonObject, Object obj) {
        final Field[] fields = getAllFields(obj.getClass());
        jsonObject.keySet().forEach(
            key -> {
                //1、得到名称相同的属性
                Field field = Arrays.stream(fields).filter(f -> f.getName().equals(key)).findFirst().orElse(null);
                if (field == null) {
                    return;
                }
                //2、判断属性的类型是否一致,如果不一致结束
                final Object value = jsonObject.get(key);
                if (!value.getClass().equals(field.getType())) {
                    return;
                }
                //3、属性一致则set值
                try {
                    field.setAccessible(true);
                    field.set(obj, value);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        );
    }

    public static Field[] getAllFields(Class clazz) {
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }

    public static String mergeJSON(JSONObject jsonObject1, JSONObject jsonObject2) {
        if (jsonObject1 == null) {
            return JSONObject.toJSONString(jsonObject2);
        }

        jsonObject1.keySet().forEach(
            key -> {
                if (jsonObject2.containsKey(key)) {
                    return;
                }
                jsonObject2.put(key, jsonObject1.get(key));
            }
        );

        return JSONObject.toJSONString(jsonObject2);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值