此博客为博主原创文章,转载请标明出处,维权必究:https://www.cnblogs.com/tangZH/p/10689536.html

更多精彩文章:http://77blogs.com/?p=301

fastjson是很好用的json解析工具,只可惜项目中要求apk体积尽量小,所以并不打算引入fastJson,只好自己写一个,遗憾的是写出的这个并没法解析所有的json数据,不过还是很值得学习的,且听我一一道来。

主要实现两个功能:

1、将jsonArray解析为List

2、将json数据转化为class

当然,class里面的成员变量的名称需要与json里面的key一样。

思路:

1、通过反射获取class类里面的成员变量名称以及类型

2、通过成员变量的名称与类型去json数据中获取该key对应的value

2、将value通过反射赋值给class对象。

具体且看:

1、定义一个实体类保存class里面的反射获取到的每个成员变量对应字段,名称,类型

static class ValueHelper {
String name;
String type;
Field field;
}

2、将json数据转换为实体类

 public static <T> T parseJson2Obj(String data, Class<T> tClass) {
if (TextUtils.isEmpty(data))
return null;
try {
List<ValueHelper> listKey;
//获得自己的所有属性
Field[] fields = tClass.getFields();
if (null == fields)
return null; listKey = new ArrayList<>(); for (Field field : fields) {
ValueHelper helper = new ValueHelper();
helper.name = field.getName();
helper.type = field.getGenericType().toString();
helper.field = field;
listKey.add(helper);
}
//将所有的属性保存在keyList集合中
//实例化给实体类,以便对其进行反射赋值
Object c = tClass.newInstance();
JSONObject object = new JSONObject(data);
for (int j = 0; j < listKey.size(); j++) {
ValueHelper helper = listKey.get(j);
//取出实体类中的属性,根据名称与类型去jsonObject中取值,
//具体实现接下来会讲
Object o = getJsonValue(helper, object);
//赋值给该实体类,具体实现记下来会讲
setProperty(c, helper.field, o);
}
//返回该实体类
return (T) c; } catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}

2.1 取出实体类中的属性,根据名称与类型去jsonObject中取值

public static Object getJsonValue(ValueHelper helper, JSONObject object) throws JSONException {
switch (helper.type) {
case "class java.lang.String":
return object.optString(helper.name, ""); case "class java.lang.Integer":
case "int":
return object.optInt(helper.name, 0); case "class java.lang.Double":
return object.optDouble(helper.name, 0); case "class java.lang.Boolean":
return object.optBoolean(helper.name, false);
}
//如果该成员变量是泛型
if (helper.field.getGenericType() instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) helper.field.getGenericType();
//判断具体类的类型,list集合或者ArrayList
if (pt.getRawType().equals(List.class) || pt.getRawType().equals(ArrayList.class)) {
//那么它对应在json中的是一个jsonArray
JSONArray array = object.getJSONArray(helper.name);
//如果集合里面的泛型为String
if (pt.getActualTypeArguments()[0].equals(String.class)) {
//将该jsonArray转化为list,具体实现接下来会讲,
//其实就相当于多次执行json转化为class,然后放入list中
//如果泛型参数为class实体类,那我就不知道该怎么解析了,
//不知道怎么判断里面的泛型参数是否为实体类
//这也是我所说的没法解析所有的json数据
List<String> sList = JsonArrayToList(array);
return sList;
}
}
} return null;
}

2.2 给实体类赋值

public static void setProperty(Object c, Field field, Object value)
throws SecurityException,
IllegalArgumentException, IllegalAccessException {
if (null == c || null == value)
return;
// 取消访问检查(私有成员变量的时候需要)
field.setAccessible(true);
// 给对象的成员变量赋值为指定的值--->value
field.set(c, value);
}

2.3 JsonArrayToList方法

public static <T> List<T> JsonArrayToList(JSONArray ja) {
List<T> ret = new ArrayList();
if (ja == null) {
return ret;
} else {
for(int i = 0; i < ja.length(); ++i) {
try {
Object obj = ja.get(i);
if (obj != null) {
ret.add(obj);
}
} catch (JSONException var4) {
;
}
} return ret;
}
}

3、将jsonArray转为list<class>,注意参数json是jsonArray数据,原理类似,就不再多讲

public static <T> List<T> parseJsonArray2List(String json, Class<? extends T> aClass) {
//反射获取所有public字段,包括父类
List<T> list = null;
List<ValueHelper> listKey;
try {
JSONArray array = new JSONArray(json);
if (null == array)
return list; //获得自己的所有属性
Field[] fields = aClass.getFields();
if (null == fields)
return null; listKey = new ArrayList<>(); for (Field field : fields) {
ValueHelper helper = new ValueHelper();
helper.name = field.getName();
helper.type = field.getGenericType().toString();
helper.field = field;
listKey.add(helper);
}
list = new ArrayList<>(); for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
Object c = aClass.newInstance();
for (int j = 0; j < listKey.size(); j++) {
ValueHelper helper = listKey.get(j);
Object o = getJsonValue(helper, object);
setProperty(c, helper.field, o);
}
list.add((T) c);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return list;
}

最新文章

  1. Ajax 加载数据 练习 自我有些迷糊了,写的大概请谅解 ^ _ ^
  2. wamp 服务器安装问题 及cmd常用命令 和 php mysql数据库常用cmd命令集
  3. C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 大数据支持分表优化
  4. VS2012使用Git并连接到osc@git
  5. 7.echo(),print(),print_r()的区别
  6. C# 闭包
  7. CAS单点登录中文用户名乱码问题
  8. Linux常用的基本命令
  9. 6.理解DispatcherServlet
  10. IOS NSPredicate 查询、搜索
  11. asp.net中Timer定时器在web中无刷新的使用
  12. Android 开发之动画详解
  13. 装多版本号sqlserver的远程连接问题
  14. github page使用
  15. pip install -r requirements.txt 安装mysqldb失败 解决方案
  16. 事务的特性(ACID)
  17. 深入了解Map
  18. day8-基础函数的学习(三)
  19. ResourceBundle类的方式来读取config.properties配置文件参数值
  20. hash_map

热门文章

  1. 计算机网络相关:应用层协议(一):DNS
  2. Hibernate中的多表查询及抓取策略
  3. spring Cloud 域名映射 ip地址实现
  4. 那些年,我们追过的RPC
  5. 【数据结构】B-Tree, B+Tree, B*树介绍
  6. RCTF 2018线上赛 writeup
  7. 富文本编辑器UEditor自定义工具栏(三、自定义工具栏功能按钮图标及工具栏样式简单修改)
  8. github代码搜索技巧
  9. Latex appendix 生成附录A和B
  10. Python configparser 读取指定节点内容失败