• java反射-变量键值对排序


    1、问题描述

    因为要做API接口安全设计方案(已实现)(https://ruanjianlaowang.blog.csdn.net/article/details/118806853 ),牵扯到前后端加密签名,从前端获取json数据后,首先需要对json数据按照首字母进行排序,再按照key1value1key2value2进行加密(json数据从前端到后端,顺序会乱),结合网上的方案,使用java的反射机制,对键值对按照首字母排序加密。

    2、解决方案

    2.1 方案

    (1)使用@RequestBody将json转换成对象;

    (2)使用反射机制获取键值对,需要使用treemap,treemap会按照首字母顺序排序插入;

    (3)从map中按顺序遍历出键值对;

    1和3就简单说一下,重点是2。

    2.2 上代码及说明

    2.2.1 实体类ReflesTes1与ReflesBase

    public class ReflesTest1 extends ReflesBase{
        private String aLaowang;
        private String bLaowang;
        private String cLaowang;
    
        public String getaLaowang() {
            return aLaowang;
        }
    
        public void setaLaowang(String aLaowang) {
            this.aLaowang = aLaowang;
        }
    
        public String getbLaowang() {
            return bLaowang;
        }
    
        public void setbLaowang(String bLaowang) {
            this.bLaowang = bLaowang;
        }
    
        public String getcLaowang() {
            return cLaowang;
        }
    
        public void setcLaowang(String cLaowang) {
            this.cLaowang = cLaowang;
        }
    }
    
    

    (2)ReflesBase类及说明

    public class ReflesBase {
        public String token;
        public String sign;
    
        public String getToken() {
            return token;
        }
    
        public void setToken(String token) {
            this.token = token;
        }
    
        public String getSign() {
            return sign;
        }
    
        public void setSign(String sign) {
            this.sign = sign;
        }
    }
    
    

    简要说明

    这里有个业务场景,就是所有从前端接受到的DTO都要有token/sign等字段,以便进行鉴权验证,需要创建个基础类来继承(有需要),为什么基类中变量是public,接下来会介绍。

    2.2.2 核心方法类ReflexUtils

    import java.lang.reflect.Field;
    import java.util.Map;
    import java.util.TreeMap;
    
    public class ReflexUtils {
        public static Map<String, Object> getKeyAndValue(Object obj) {
            Map<String, Object> map = new TreeMap<String, Object>();
            // 得到类对象
            Class userCla = (Class) obj.getClass();
            /* 得到类中的所有属性集合 */
            Field[] fs = userCla.getDeclaredFields();
            for (int i = 0; i < fs.length; i++) {
                Field f = fs[i];
                f.setAccessible(true); // 设置些属性是可以访问的
                Object val = new Object();
                try {
                    val = f.get(obj);
                    // 得到此属性的值
                    map.put(f.getName(), val);// 设置键值
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
    
            }
    
            Field[] fs2 = userCla.getFields();
            for (int i = 0; i < fs2.length; i++) {
                Field f = fs2[i];
                f.setAccessible(true); // 设置些属性是可以访问的
                Object val = new Object();
                try {
                    val = f.get(obj);
                    // 得到此属性的值
                    map.put(f.getName(), val);// 设置键值
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
    
            }
            return map;
        }
    
        public static void main(String[] args) {
            ReflesTest1 test1 = new ReflesTest1();
            test1.setaLaowang("aaaa");
            test1.setbLaowang("bbbb");
            test1.setcLaowang("cccc");
    
            test1.setToken("fdaflkjdskfj ");
    
              Map<String, Object> map = getKeyAndValue(test1);
            System.out.println(map);
    
            for (String s : map.keySet()) {
                String value =  (String) map.get(s);
                if (value != null) {
                    System.out.println(s+value);
                }
    
            }
        }
    }
    

    简要说明:

    (1)从代码看,其实也很简单,就是利用反射机制进行变量的获取。

    (2)利用用到的是treemap,该map子类可以实现按字典排序(按首字母顺序),也可以自定义。

    (TreeMap 默认排序规则:按照key的字典顺序来排序(升序),当然,也可以自定义排序规则:要实现Comparator接口。)

    (3) Field[] fs = userCla.getDeclaredFields();方法中同时使用了getDeclaredFields和getFields方法。

    getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。

    getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段;

    组合起来就满足业务场景了。

    (4)map遍历,合并keyvalue

    2.3 效果


    更多信息请关注公众号:「软件老王」,关注不迷路,软件老王和他的IT朋友们,分享一些他们的技术见解和生活故事。

    更多信息请关注公众号:「软件老王」,关注不迷路,IT技术与相关干货分享,回复关键字获取对应干货,本文版权归作者软件老王所有,转载需注明作者、超链接,否则保留追究法律责任的权利。
  • 相关阅读:
    WPF Step By Step -基础知识介绍
    WPF Step By Step 系列
    设计模式的六大原则
    Java实现二维码生成的方法
    Java 导出Excel
    解析图书 XML
    Maven搭建Spring+SpringMVC+Mybatis+Shiro项目详解
    springboot配置文件的所有属性
    SpringBoot中 application.yml /application.properties常用配置介绍
    Linux 系统目录结构
  • 原文地址:https://www.cnblogs.com/ruanjianlaowang/p/15060572.html
Copyright © 2020-2023  润新知