如何优雅的反射得到Bean,无视属性类型

2017-12-27 19:14:22来源:CSDN作者:mtj66人点击

分享

从hbase中得到了scan结果如果不用spring hbase 模块如何自己实现解析。
这个是在使用hbase中的一个难题。

下面就用 hbase中的结果作为实例,展示一下。如果有更好的方法,请回复哦,相互学习。
该解析工具类经过几次抽象迭代,得到的结果,通用性很高,特来分享下。
在github 中也有完整的使用,请查收,欢迎follow。

import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.List;import org.apache.hadoop.hbase.Cell;import org.apache.hadoop.hbase.CellUtil;import org.apache.hadoop.hbase.client.Result;import org.apache.hadoop.hbase.util.Bytes;/** *  * 解析工具,对代码进行抽取,避免bean类型的依赖,提高代码的通用性 如何优雅的反射出一个对象 *  * @author sh04595 20171220 *  * @param <T> Bean Type */public class ParserUtils<T> {    // private static final Field[] fields = User.class.getDeclaredFields();    // private static final String keyField = "userId";    // private static final byte[] family = Bytes.toBytes("f1");    // private static final byte[] col_name = Bytes.toBytes("name");    // private static final byte[] col_age = Bytes.toBytes("age");    /**     * 优雅解析User,根据bean属性类型自动判断处理赋值问题     *      * @param rs     *            scan result     * @param clazz     *            bean class     * @param keyField     *            table中key对应的属性     * @return bean     * @throws Exception     */    public static <T> T parser2Bean(Result rs, Class<T> clazz, String keyField)            throws Exception {        Field[] fields = clazz.getDeclaredFields();        List<Cell> listCells = rs.listCells();        T user = clazz.newInstance();        // 遍历key对应的所有Cell        for (Cell cell : listCells) {            String key = Bytes.toString(CellUtil.cloneRow(cell));            // String cloneFamily = Bytes.toString(CellUtil.cloneFamily(cell));            // // 列簇名            String cloneQualifier = Bytes.toString(CellUtil                    .cloneQualifier(cell)); // 列名            String cloneValue = Bytes.toString(CellUtil.cloneValue(cell)); // 列值            for (Field field : fields) { // 遍历所有的属性                //Object value = null;                String fieldName = field.getName();                // 处理key对应的属性                if (fieldName.equalsIgnoreCase(keyField)) {                    // 此處可以賦值也可以不賦值,引用改變                    user = invokField(clazz, keyField, user, key, field);                } else if (fieldName.equalsIgnoreCase(cloneQualifier)) {                    invokField(clazz, fieldName, user, cloneValue, field);                    break;                }            }        }        return user;    }    /**     * 根據具體的屬性進行處理     * @param clazz     * @param keyField     * @param user     * @param key     * @param field     * @throws NoSuchMethodException     * @throws IllegalAccessException     * @throws InvocationTargetException     */    private static <T> T invokField(Class<T> clazz, String keyField, T user,            String key, Field field) throws NoSuchMethodException,            IllegalAccessException, InvocationTargetException {        Object value;        String mathodName = "set" + toUpperCase4Index(keyField);        value = getFieldValue(key, field);        Method keymethod = clazz.getMethod(mathodName, field.getType());        keymethod.invoke(user, value); // 执行反射,对属性进行set vale        return user;    }    /**     * 根据需要传入的value 解析成制定的类型的Object,比如 Double,Integer ref     * https://www.zhihu.com/question/67687909     *      * @param sValue     *            source string value     * @param field     *            object field     * @return field relevant value     * @throws NoSuchMethodException     * @throws IllegalAccessException     * @throws InvocationTargetException     */    private static Object getFieldValue(String sValue, Field field)            throws NoSuchMethodException, IllegalAccessException,            InvocationTargetException {        Object value = null;        Class<?> fieldType = field.getType();        if (fieldType == String.class)            value = sValue;        else {            Method methodType = fieldType.getMethod("parse"                    + fixparse(fieldType.getSimpleName()), String.class);            value = methodType.invoke(null, sValue);        }        return value;    }    /**     * 当属性为 Integer的时候特殊处理     *      * @param fstype     * @return     */    private static String fixparse(String fstype) {        switch (fstype) {        case "Integer":            return "Int";        default:            return fstype;        }    }    /**     * 首字母大写     *      * @param string     * @return     */    public static String toUpperCase4Index(String string) {        char[] methodName = string.toCharArray();        methodName[0] = toUpperCase(methodName[0]);        return String.valueOf(methodName);    }    /**     * 字符转成大写     *      * @param chars     * @return     */    public static char toUpperCase(char chars) {        if (97 <= chars && chars <= 122) {            chars ^= 32;        }        return chars;    }}

当然写入hbase中也是有一套解决方案,不用硬代码生成put。
下面是实例,目前还没放到github上。

private static final byte[] CF_INFO = Bytes.toBytes("cfInfo");private static final Field[] fields = VhlData.class.getDeclaredFields();for (Field field : fields) {                    String fieldName = field.getName();                    String fieldValue = (String) field.get(vhlData);                    if (fieldValue != null && fieldValue.length() > 0) {                        p.add(CF_INFO, Bytes.toBytes(fieldName), Bytes.toBytes(fieldValue));                    }}

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台