美文网首页
记录一次工作中中使用反射

记录一次工作中中使用反射

作者: 我们的天空L | 来源:发表于2020-07-27 15:11 被阅读0次

    在很多的框架底层,都用到了java反射的原理,当初在学习java基础的时候,在反射这块,也只是稍稍的过了一下,因为一般只有需要写框架,或者去看框架的底层源码的时候,才会用到反射的知识点。
    这次,工作中遇到一个问题,那就是需要使用java,充当一个中间商的角色,A服务调用我的java服务给我推送数据,我再通过公安提供的接口地址将数据推送给公安的服务,使用json格式来做中间数据的传输。但是,公安的接口文档中,所有的请求参数都是大写字母加下划线的格式,例如:

    { 
      "MJJCJLXXBZ":"门禁进出XXX",
      "GLDMJ_CJSBXXBZ":"关联的门禁采集XXX"
      ....
    }
    

    所有的接口的参数都是这种格式,大概有10几个接口,这些数据都是A服务推送给我的,所以就涉及到我这里需要写对应的Bean来接收这些参数,并将这些Bean转换成公安需要的json格式推送给公安。其实我完全可以用公安的这种数据格式,来声明一个个类,这样我就不用转换。

    class Bean {
      private String MJJCJLXXBZ;
      private String GLDMJ_CJSBXXBZ;
      ....
    }
    

    这样做不是不可以,但是违反了java的小驼峰的命名方式,对于我这样有轻微洁癖的人是接受不了的,所以我将其换成常规的java小驼峰的命名格式。

    class Bean {
      private String mjjcjlxxbz;
      private String gldmjCjsbxxbz;
      ....
    }
    

    这样A服务给我推送数据的时候,就采用这种小驼峰的格式,而我接收数据就使用这个bean来接收。但是我还需要将数据转换成公安接口需要的那种格式才能推送成功,传统办法是将bean里一个个字段都进行手动的转换,但是这样的方式并不可取,所以需要写一个通用的方法,进行操作,
    此操作要具有通用性,所以我尝试使用泛型+反射来实现上述需求。
    实现代码如下:

    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.LinkedHashMap;
    import java.util.Map;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     *
     *
     *@classname RequestData
     *@author 刘岩松
     *@date 2020/6/23 16:31
     */
    public class RequestData {
    
        private static Pattern AZ_PATTERN = Pattern.compile("[A-Z]");
        private static Pattern UNDERLINE_PATTERN = Pattern.compile("_([a-z])");
    
        public static <T> Map<String, String> generation(T data) {
            Map<String, String> result = new LinkedHashMap<>();
            Class<?> clazz = data.getClass();
            try {
                for (Field field : clazz.getDeclaredFields()) {
                    String key = underline(field.getName()).toUpperCase();
                    //利用反射执行目标方法获取值
                    Method method = clazz.getMethod("get" + field.getName().substring(0, 1).toUpperCase().concat(field.getName().substring(1)));
                    String value = (String) method.invoke(data);
                    result.put(key, value);
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    
        /**
         * 将驼峰格式字符串转下划线格式
         *
         * @param str 待处理字符串
         * @author 刘岩松
         * @date 2020/6/23 16:55
         */
        private static String underline(String str) {
            //正则匹配大写字符转成小写并在前面加上下划线
            Matcher matcher = AZ_PATTERN.matcher(str);
            StringBuffer sb = new StringBuffer(str);
            if (matcher.find()) {
                sb = new StringBuffer();
                //将当前匹配的子串替换成指定字符串,
               //并且将替换后的子串及之前到上次匹配的子串之后的字符串添加到StringBuffer对象中
                //正则之前的字符和被替换的字符
                matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
                //把之后的字符串也添加到StringBuffer对象中
                matcher.appendTail(sb);
            } else {
                return sb.toString();
            }
            return underline(sb.toString());
        }
    
        /**
         *
         *将下划线格式字符串转驼峰格式
         *
         * @param str string 待处理字符串
         * @author 刘岩松
         * @date 2020/6/23 16:00
         */
        private static String camel(String str) {
            //正则匹配下划线及后一个字符,删除下划线并将匹配的字符转成大写
            Matcher matcher = UNDERLINE_PATTERN.matcher(str);
            StringBuffer sb = new StringBuffer(str);
            if (matcher.find()) {
                sb = new StringBuffer();
                //将当前匹配的子串替换成指定字符串,
                //并且将替换后的子串及之前到上次匹配的子串之后的字符串添加到StringBuffer对象中
                //正则之前的字符和被替换的字符
                matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
                //把之后的字符串也添加到StringBuffer对象中
                matcher.appendTail(sb);
            } else {
                return sb.toString();
            }
            return camel(sb.toString());
        }
    }
    
    

    相关文章

      网友评论

          本文标题:记录一次工作中中使用反射

          本文链接:https://www.haomeiwen.com/subject/fzuzlktx.html