龙空技术网

java反射-变量键值对排序

软件老王 225

前言:

当前兄弟们对“键值对java”大约比较看重,大家都想要剖析一些“键值对java”的相关知识。那么小编在网摘上搜集了一些对于“键值对java””的相关资讯,希望大家能喜欢,咱们一起来了解一下吧!

1、问题描述

因为要做API接口安全设计方案(已实现),牵扯到前后端加密签名,从前端获取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朋友们,分享一些他们的技术见解和生活故事。

标签: #键值对java