项目中做单点登录系统集成时,需要对集成方系统提供接口服务,用于同步机构信息、用户信息等数据,要求接口满足1.MQ消息中间件推送,2.WebService方式,3.Rest服务方式,4.HTTP请求方式。所幸最终规定数据格式统一返回json格式。格式如下:
{
"code": 0,
"desc": "成功请求数据",
"dataobj": [
{
"action": "I",
"deptCode": "000000AA",
"deptName": "*****",
"shortName": "*****",
"parentCode": "000000A",
"parentName": "###",
"deptKind": ""
"deptType": "机构属性"
"deptStatus": "机构状态"
"deptAddr": "大"
"centreX": "103.35"
"centreY": "56.47"
"areaCode": "210200"
},
{
"action": "U",
"deptCode": "000000AA",
"deptName": "*****",
"shortName": "*****",
"parentCode": "",
"parentName": "",
"deptKind": ""
"deptType": "机构属性"
"deptStatus": "机构状态"
"deptAddr": ""
"centreX": "127.35"
"centreY": "86.47"
"areaCode": "210200"
}
]
}
由于Rest服务是可以直接返回实体对象并自动转为json格式的,考虑到代码的复用性,webservice和http请求的两种接口方式只需要将rest服务获取到的对象转成json即可。思路定下来,开始写类。
package com.soa.service.model;
import java.util.List;
public class WsModel
{
private String code;
private String desc;
private List<Object> dataobj = null;
public String getCode()
{
return code;
}
public void setCode(String code)
{
this.code = code;
}
public String getDesc()
{
return desc;
}
public void setDesc(String desc)
{
this.desc = desc;
}
public List<Object> getDataobj()
{
return dataobj;
}
public void setDataobj(List<Object> dataobj)
{
this.dataobj = dataobj;
}
}
到了这一步,现在要做的就是只需要获取WsModel对象即可,三种接口方式均可实现。其中dataobj即为具体的业务对象列表数据。由于接口数据都是通过sql从数据库表中查出来的List列表,那么怎么转换成我们需要的dataobj对象列表呢,下面就是今天要说的,通过java的反射机制将列表转换成对象。直接贴代码:
package com.soa.service.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.common.util.StringUtil;
public class ConvertUtil
{
/**
* 该方法是将传入的一个集合列表转换成对象列表
* 注意:对象的属性个数要和传入的列表个数及顺序一一对应
* 2015-12-18
* @param dataList
* @param cl
* @return
* author:wangZhen
*/
public static List List2Object(List dataList, Class cl)
{
try
{
if (dataList != null && dataList.size() > 0)
{
List modelList = new ArrayList();
for (int k = 0; k < dataList.size(); k++)
{
List row = (List) dataList.get(k);
// 获取实体类的所有属性,返回Field数组
Field[] fields = cl.getDeclaredFields();
Object obj = cl.newInstance();
for (int i = 0; i < fields.length; i++)
{
Field field = fields[i];
// 打印该类的所有属性类型
// System.out.println(field.getGenericType());
// System.out.println(field.getName());
// 如果类型是String
if (field.getGenericType().toString().equals("class java.lang.String"))
{
// 拿到该属性的gettet方法
Method m;
String methodName = "set" + getMethodName(field.getName());
m = (Method) obj.getClass().getMethod(methodName, new Class[]
{ String.class });
m.invoke(obj, new Object[]
{ StringUtil.convertNull(row.get(i)) });// 调用setter方法设置属性值
}
//如果是****类型 如果需要转换的对象有其余格式的属性,如List 此处有两点需要注意,
//1. row.get(i)从列表将将值取出来的时候需要强转类型
//2. 定义方法Method 的时候方法参数的属性也要注意要一一对应
/**
* if语句里面是不是特别麻烦?
* 还需要设置参数类型?
* 其实也可以用这种方式给对象设置值
// 获取原来的访问控制权限
boolean accessFlag = fields[i].isAccessible();
// 修改访问控制权限
fields[i].setAccessible(true);
field.set(obj, row.get(i));
// 恢复访问控制权限
fields[i].setAccessible(accessFlag);
*/
}
modelList.add(obj);
}
return modelList;
}
} catch (SecurityException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 该方法是根据传入的对象获取一个相对性的map集合
* key:属性名,value:属性值
* 2015-12-18
* @param obj
* @return
* author:wangZhen
*/
public static Map object2Map(Object obj){
Map<String, String> map = new HashMap<String, String>();
try
{
// 获取实体类的所有属性,返回Field数组
Field[] fields = obj.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++)
{
Field field = fields[i];
String fieldName = field.getName();
// 获取原来的访问控制权限
boolean accessFlag = fields[i].isAccessible();
// 修改访问控制权限
fields[i].setAccessible(true);
// 获取在对象f中属性fields[i]对应的对象中的变量
Object fieldValue = fields[i].get(obj);
if (fieldValue != null){
map.put(fieldName, fieldValue.toString());
}
// 恢复访问控制权限
fields[i].setAccessible(accessFlag);
}
} catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;
}
/**
* 该方法是将传入的属性名第一个字母大写 2015-12-17
*
* @param fildeName
* @return
* @throws Exception
* @author:wangZhen
*/
private static String getMethodName(String fildeName) throws Exception
{
byte[] items = fildeName.getBytes();
items[0] = (byte) ((char) items[0] - 'a' + 'A');
return new String(items);
}
}
示例中提供了两种方式的赋值实现,给出了将列表转换成对象列表的方式,与其对应的也给出了将对象转成Map的方法,初衷是想将对象也转成list列表的,但是转换了之后发现运用起来还不是太灵活,只能根据对象属性的顺序依次取出对象的属性值,这样对对象的依赖性还是比较大的,对象属性变更后程序可能会受到影响。最终考虑还是转成map比较合适,具体怎么转换看每个人的业务需求。 通过该方法转换最终产生的接口数据如下所示: