最近由于业务需求,在跟其他的系统进行通信时要求对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}