最近由于业务需求,在跟其他的系统进行通信时要求对pojo中的域进行排序,然后域的升序或降序再转化成String,即双方进行md5校验时按照相同的规则
根据需求利用发射写了个工具类,给大家分享出来,供大家参考
/**
* 按照给定类的域进行排序,然后用指定的分割符进行分割<br/> * @param instance 需要操作的类的实例 * @param desc 如果true表示降序,如果是false按照升序 * @param separator 域之间的分隔符 * @param arraySymbol 数组的外围符号开始标签,例如:json的数组都用[]作为数组内部元素的外围标签,此处指[ * @param arrayEndSymbol 数组的外围符号开始标签,例如:json的数组都用[]作为数组内部元素的外围标签,此处指] * @return */ public static String objectToStringByFieldOrder(Object instance,boolean desc,String separator,String arrayBeginSymbol,String arrayEndSymbol) { Class<? extends Object> clzss = instance.getClass(); Field[] allField = clzss.getDeclaredFields();//注意此处可能包含了所有的域即包含public/protected/private等 List<Integer> orderList = new ArrayList<Integer>();//记录每个域在allField位置 //此处由于业务关系,只需要private范围的域,对所有的name进行排序 for(int k=0;k<allField.length;k++) { if(Modifier.isPrivate(allField[k].getModifiers())) { if(k==0) { orderList.add(k); continue; } boolean isadd = false; for(int t=0;t<orderList.size();t++) { if(desc)//降序 { if(allField[k].getName().compareTo(allField[orderList.get(t)].getName()) >=0) { isadd = true; orderList.add(t, k); break; } }else{//升序 if(allField[k].getName().compareTo(allField[orderList.get(t)].getName()) <=0) { isadd = true; orderList.add(t, k); break; } } } if(!isadd) { orderList.add(k); } } } StringBuilder builder = new StringBuilder(); builder.append("{"); //根据排好序的内容进行字符串转换 for(int m=0;m<orderList.size();m++) { if(m!=0) { builder.append(separator); } allField[orderList.get(m)].setAccessible(true);//私有的,默认是不允许访问的 Object value = null; try { value = allField[orderList.get(m)].get(instance); } catch (Exception e) { logger.error("Get value from the instance failed.the field name is "+allField[orderList.get(m)].getName(),e); //此处不做处理直接跳过去 } if(null == value) { continue; } if(value instanceof List)//有些pojo中含有list对象,注意此处可能会有对象嵌套对象,即list嵌套list { //此处实际上是个递归的调用 List inner_list = (List)value; if(inner_list.size()>0) { //注意此处可能也需要定制,应为数组在传递时可能顺序发生变化,如果计算MD5时,就会发生变化,所以此处应该根据业务对list进行排序(系统定制方面的就不贡献了) builder.append(allField[orderList.get(m)].getName()+"="+arrayBeginSymbol); for(int n=0;n<inner_list.size();n++) { //此处需要分析,list中的内容是否是基本类型,如果是基本类型则直接处理,如果不是则需要递归调用 if(null == inner_list.get(n)) continue; if(inner_list.get(n) instanceof java.lang.String)//因为我们这边的pojo只有string,所以只判断string,如果有其他基本类型,也需要添加 { builder.append(inner_list.get(n)); }else{ builder.append(objectToStringByFieldOrder(inner_list.get(n), desc, separator,arrayBeginSymbol,arrayEndSymbol)); } if(n< inner_list.size()-1) { builder.append(separator); } } builder.append(arrayEndSymbol); } }else{ builder.append(allField[orderList.get(m)].getName()).append("=").append(value); } } builder.append("}"); System.err.println("----------------------------------------"+builder.toString()); return builder.toString(); }//测试
先创建一个简单的people类:
public class People {
private String name; private int age; private String sex; private String mobile; public String grade; protected String birthday; private List<String> friends; private List<Child> childs; //setter getter就不写了}
创建一个child类:
public class Child {
private String childName; private String childMobile; //setter getter就不写了}开始测试:
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
People p = new People(); p.setName("zwb"); p.setAge(25); p.setSex("男"); p.setGrade("大学"); p.setMobile("1233456789"); p.setBirthday("1990-11-27"); List<String> str = new ArrayList<String>(); str.add("zhangsan"); str.add("lisi"); str.add("王五"); p.setFriends(str); List<Child> ch = new ArrayList<Child>(); Child child1 = new Child(); child1.setChildMobile("childMobile1"); child1.setChildName("childName1"); Child child2 = new Child(); child2.setChildMobile("childMobile2"); child2.setChildName("childName2"); ch.add(child1); ch.add(child2); p.setChilds(ch); System.err.println("-----:"+objectToStringByFieldOrder(p, true, "_","[","]")); }运行结果:
----------------------------------------{childName=childName1_childMobile=childMobile1}
----------------------------------------{childName=childName2_childMobile=childMobile2}----------------------------------------{sex=男_name=zwb_mobile=1233456789_friends=[zhangsan_lisi_王五]_childs=[{childName=childName1_childMobile=childMobile1}_{childName=childName2_childMobile=childMobile2}]_age=25}-----:{sex=男_name=zwb_mobile=1233456789_friends=[zhangsan_lisi_王五]_childs=[{childName=childName1_childMobile=childMobile1}_{childName=childName2_childMobile=childMobile2}]_age=25}完成!