利用JAVA反射机制将列表转为对象

         项目中做单点登录系统集成时,需要对集成方系统提供接口服务,用于同步机构信息、用户信息等数据,要求接口满足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比较合适,具体怎么转换看每个人的业务需求。  通过该方法转换最终产生的接口数据如下所示:

223932_l12Q_2559164.png



转载于:https://my.oschina.net/wangzhen9005/blog/600211

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值