JAVA BEAN反射组装数据小工具

3 篇文章 0 订阅
2 篇文章 0 订阅

之前开发java服务端,因为查询使用的是SpringData,好多一查询都都查出来了,返回给前端好多数据都是没用的,自己抽空做了一个小工具,用来反射字段

 

package test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class EntityUtils {
    // 格式化标识符
    public static final String format_separator_pattern = "\\|";
    public static final String format_separator_str = "|";

    // 别名标识符
    public static final String alias_separator_pattern = "\\:";
    public static final String alias_separator_str = ":";

    // 组合类标识符
    public static final String children_separator_pattern = "\\.";
    public static final String children_separator_str = ".";

    // 是否开启DEBUG模式
    public static final boolean DEBUG = false;

    // 时间类型
    @SuppressWarnings("rawtypes")
    public final static List dateTypes = Arrays.asList(java.util.Date.class, java.sql.Timestamp.class,
            java.sql.Date.class);

    // 数字类型
    @SuppressWarnings("rawtypes")
    public final static List numberTypes = Arrays.asList(Integer.class, Long.class, Float.class, Double.class,
            BigDecimal.class);

    // 集合类型数组
    @SuppressWarnings("rawtypes")
    public final static List basicCollections = Arrays.asList(List.class, Set.class);

    // 自动格式化的几种类型,其他类型不做处理
    public final static String dateType = "date";// 时间类型
    public final static String numberType = "number";// 数字类型

    /**
     * 获取类对象中所有的基本属性字段名称
     *
     * @param entityClass
     *            类对象
     * @return {@link List}<{@link String}> 属性字段名称数组
     */
    public static List<String> getDeclaredFields(Class<?> entityClass) {
        List<String> fields = new ArrayList<>();
        // 检查是否有父类,如果继承了Object以外的其他父类,则获取父类的属性
        Class<?> superClass = entityClass.getSuperclass();
        if (superClass != null && (superClass != Object.class)) {
            fields.addAll(getDeclaredFields(entityClass.getSuperclass()));
        }
        // 获取类所有的列
        Field[] fs = entityClass.getDeclaredFields();
        // 便利列名称,并且添加到字符串数组中
        for (Field field : fs) {
            fields.add(field.getName());
        }

        return fields;
    }

    /**
     * 获取类对象中所有的基本属性字段名称,并去除部分字段
     *
     * @param entityClass
     *            类对象
     * @return {@link List}<{@link String}> 属性字段名称数组
     */
    public static List<String> getDeclaredFields(Class<?> entityClass, String... removeFields) {
        List<String> fields = EntityUtils.getDeclaredFields(entityClass);
        fields.removeAll(Arrays.asList(removeFields));
        return fields;
    }

    /**
     * 根据传递的的keys参数来获取obj中所对应字段的值,转换为一个Map返回
     *
     * @param entity
     *            已经实例化的对象
     * @param keys
     *            需要获取的对象字段的数组
     * @return {@link Map}
     */
    public static Map<String, Object> getDeclaredParameters(Object entity, List<String> keys) {
        Map<String, Object> result = new HashMap<String, Object>();
        Map<String, Object> children = new HashMap<String, Object>();

        printlnLog("开始遍历类中所有的字段");
        for (String key : keys) {
            // 去除格式化信息的KEY
            String basicKey = getBasicKey(key);
            String firstKey = getFirstKey(basicKey);

            // 如果有二级遍历,则保存二级遍历信息
            if (basicKey.contains(EntityUtils.children_separator_str)) {
                addChildrenKey(key, children);
            } else {
                try {
                    // 获取传递进来的对象类
                    Class<?> entityClass = entity.getClass();

                    String methodName = EntityUtils.getMethodName(firstKey);
                    Method method = entityClass.getMethod(methodName);
                    Object value = method.invoke(entity);
                    Class<?> type = method.getReturnType();

                    value = getValue(value, type, key);
                    String mapKey = getMapKey(key);

                    result.put(mapKey, value);

                } catch (NoSuchMethodException | SecurityException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }

        }

        EntityUtils.getDeclaredChildrenParameters(result, children, entity);

        return result;
    }

    /**
     * 根据传递的的keys参数来获取objs数组中所对应字段的值,转换为一个Map返回
     *
     * @param collection
     *            已经实例化的对象数组
     * @param keys
     *            需要获取的对象字段的数组
     * @return {@link List}<{@link Map}<{@link String},{@link Object}>>
     */
    public static List<Map<String, Object>> getListDeclaredParameters(Collection<?> collection, List<String> keys) {
        List<Map<String, Object>> result = new ArrayList<>();
        if (null != collection && 0 < collection.size()) {
            result = new ArrayList<Map<String, Object>>();
            for (Object obj : collection) {
                result.add(EntityUtils.getDeclaredParameters(obj, keys));
            }
        }

        return result;
    }

    /**
     * 获取二级或二级以下字段的值,转换为一个Map返回
     *
     * @param result
     *            一级的返回值
     * @param children
     *            子类的key
     * @param superEntity
     *            主类的类型
     */
    private static void getDeclaredChildrenParameters(Map<String, Object> result, Map<String, Object> children,
            Object superEntity) {
        printlnLog("children:" + children.keySet());
        Set<String> keySet = children.keySet();

        // 获取传递进来的对象类
        Class<?> entityClass = superEntity.getClass();

        for (String childrenKey : keySet) {
            // 去除格式化信息的KEY
            String basicKey = getBasicKey(childrenKey);
            String firstKey = getFirstKey(basicKey);
            try {
                String methodName = getMethodName(firstKey);
                Method method = entityClass.getMethod(methodName);
                Object subObject = method.invoke(superEntity);
                if (null != subObject) {
                    // 获取子分支所需要获取的字段名称数组
                    @SuppressWarnings("unchecked")
                    List<String> subKeys = (ArrayList<String>) children.get(childrenKey);
                    // 如果子元素是数组类型,则反射数组中的信息
                    if (EntityUtils.basicCollections.contains(method.getReturnType())) {
                        result.put(childrenKey, getListDeclaredParameters((Collection<?>) subObject, subKeys));
                    } else {
                        result.put(childrenKey, getDeclaredParameters(subObject, subKeys));
                    }
                } else {
                    result.put(childrenKey, null);
                }
            } catch (NoSuchMethodException | SecurityException e) {
                e.printStackTrace();
            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 如果字段使用了别名,这里会直接返回别名,如果没有则返回正常字段名称
     *
     * @param key
     * @return
     */
    private static String getMapKey(String key) {
        String basicKey = getBasicKey(key);
        printlnLog("获取字段的名称[key=" + key + "]");
        if (basicKey.contains(EntityUtils.alias_separator_str)) {
            return basicKey.split(EntityUtils.alias_separator_pattern)[1].trim();
        }

        return key;
    }

    /**
     * 获取值,在这里面会自动进行格式化和转换等操作
     *
     * @param value
     *            需要格式化的值
     * @param type
     *            数据类型
     * @param key
     *            字段名称
     * @return
     */
    public static Object getValue(Object value, Class<?> type, String key) {
        printlnLog("获取字段值,这里会做自动化处理[value=" + value + ",type=" + type + ",key=" + key + "]");
        if (EntityUtils.needPattern(key)) {
            return format(value, key);
        } else if (dateTypes.contains(type)) {
            return ((Date) value).getTime();
        }
        return value;
    }

    /**
     * 格式化值
     *
     * @param value
     *            需要格式化的值
     * @param key
     *            需要格式化的字段名称
     * @return
     */
    private static Object format(Object value, String key) {
        String pattern = getPattern(key);
        String formatType = getObjectType(value);
        printlnLog("格式化值[pattern:" + pattern + ",formatType:" + formatType + "]");

        return format(value, pattern, formatType);
    }

    /**
     * 格式化值
     *
     * @param value
     *            需要格式化的值
     * @param pattern
     *            格式化模式
     * @param formatType
     *            格式化类型
     * @return
     */
    private static Object format(Object value, String pattern, String formatType) {
        switch (formatType) {
        case EntityUtils.dateType: {
            return dateFormat(value, pattern);
        }
        case EntityUtils.numberType: {
            return numberFormat(value, pattern);
        }
        default:
            return value;
        }
    }

    /**
     * 日期类型格式化
     *
     * @param object
     *            格式化的对象
     * @param pattern
     *            格式的模式字符串
     * @return 完成格式化的信息
     */
    private static String dateFormat(Object object, String pattern) {
        printlnLog("dateFormat:[object=" + object + ",pattern=" + pattern + "]");
        if (object == null) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.format(object);
    }

    /**
     * 数字类型格式化
     *
     * @param object
     *            格式化的对象
     * @param pattern
     *            格式的模式字符串
     * @return 完成格式化的信息
     */
    private static String numberFormat(Object object, String pattern) {
        printlnLog("numberFormat:[object=" + object + ",pattern=" + pattern + "]");
        if (object == null) {
            return null;
        }
        DecimalFormat formatter = new DecimalFormat(pattern);
        return formatter.format(object);
    }

    /**
     * 获取需要格式化的字段的数据类型
     *
     * @param object
     * @return
     */
    private static String getObjectType(Object object) {
        printlnLog("获取当前字段可以自动格式化的类型[object=" + object + "]");
        if (object == null) {
            throw new RuntimeException("The object can not be null");
        }

        if (EntityUtils.numberTypes.contains(object.getClass())) {
            return EntityUtils.numberType;
        }

        if (EntityUtils.dateTypes.contains(object.getClass())) {
            return EntityUtils.dateType;
        }

        throw new RuntimeException("只支持数字与实践类型的格式化");
    }

    /**
     * 获取格式化模式字符串
     *
     * @param key
     *            需要格式化的字段名称
     * @return
     */
    private static String getPattern(String key) {
        printlnLog("获取格式化字符串[key=" + key + "]");
        return key.split(EntityUtils.format_separator_pattern)[1].trim();
    }

    /**
     * 判断是否需要格式化
     *
     * @param key
     * @return
     */
    private static boolean needPattern(String key) {
        printlnLog("判断是否需要格式化[key=" + key + "]");
        String basicKey = EntityUtils.getBasicKey(key);
        if (basicKey.contains(EntityUtils.children_separator_str)) {
            return false;
        }

        return key.contains(EntityUtils.format_separator_str);
    }

    /**
     * 根据传递进来的KEY来判断是否存在格式化相关分隔符<br>
     * 如果存在则去除分隔符之后的东西,自动去除拆分后的前后空格<br>
     * 例:传递进来的key="createTime | yyyy-MM-dd" ,返回的内容为"createTime"
     *
     * @param key
     * @return
     */
    public static String getBasicKey(String key) {
        printlnLog("获取基本字段名称,去除了格式化信息[key=" + key + "]");
        // 判断是否存在格式化标识符
        if (key.contains(EntityUtils.format_separator_str)) {
            return key.split(EntityUtils.format_separator_pattern)[0].trim();
        }
        return key;
    }

    /**
     * 获取key中的第一级名称<br>
     * 例:传递进来的key="user.name",返回的内容为"user"
     *
     * @param key
     * @return
     */
    public static String getFirstKey(String key) {
        printlnLog("获取当前一级类字段名称[key=" + key + "]");
        // 判断是否存在二级
        if (key.contains(EntityUtils.children_separator_str)) {
            String firstKey = key.split(EntityUtils.children_separator_pattern)[0].trim();
            return removeAlias(firstKey);
        }

        return removeAlias(key);
    }

    /**
     * 去除别名
     *
     * @param key
     * @return
     */
    public static String removeAlias(String key) {
        printlnLog("去除别名[key=" + key + "]");
        if (key.contains(EntityUtils.alias_separator_str)) {
            return key.substring(0, key.indexOf(EntityUtils.alias_separator_str)).trim();
        }
        return key;
    }

    /**
     * 添加二级的KEY
     *
     * @param key
     * @param children
     */
    public static void addChildrenKey(String key, Map<String, Object> children) {
        String firstKey = getFirstKey(key);
        @SuppressWarnings("unchecked")
        List<String> childrenKeyList = (ArrayList<String>) children.get(firstKey);
        if (null != childrenKeyList) {
            childrenKeyList.add(key.replaceFirst(firstKey.concat("."), ""));
        } else {
            childrenKeyList = new ArrayList<>();
            childrenKeyList.add(key.replaceFirst(firstKey.concat("."), ""));
            children.put(firstKey, childrenKeyList);
        }
    }

    /**
     * 根据字段名称获取该字段的get方法
     *
     * @param key
     *            字段名称
     * @return
     */
    public static String getMethodName(String key) {
        if (null == key || "".equals(key) || 0 > key.length()) {
            return null;
        }

        char[] buf = key.toCharArray();
        buf[0] = Character.toUpperCase(buf[0]);
        return "get".concat(String.valueOf(buf));
    }

    /**
     * 打印信息
     *
     * @param message
     */
    private static void printlnLog(String message) {
        if (EntityUtils.DEBUG) {
            System.out.println(message);
        }
    }

}


主要的作用呢,就是通过反射来组装Map并返回,可以自定义返回bean中的那些字段,支持别名,简单的格式化之类的,如果感觉比较烂请喷,我会继续优化的

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值