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 classValueHelper {
String name;
String type;
Field field;
}
2、将json数据转换为实体类
public static T parseJson2Obj(String data, ClasstClass) {if(TextUtils.isEmpty(data))return null;try{
ListlistKey;//获得自己的所有属性
Field[] fields =tClass.getFields();if (null ==fields)return null;
listKey= new ArrayList<>();for(Field field : fields) {
ValueHelper helper= newValueHelper();
helper.name=field.getName();
helper.type=field.getGenericType().toString();
helper.field=field;
listKey.add(helper);
}
//将所有的属性保存在keyList集合中
//实例化给实体类,以便对其进行反射赋值
Object c=tClass.newInstance();
JSONObject object= newJSONObject(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) throwsJSONException {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() instanceofParameterizedType) {
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 sList =JsonArrayToList(array);returnsList;
}
}
}return null;
}
2.2 给实体类赋值
public static voidsetProperty(Object c, Field field, Object value)throwsSecurityException,
IllegalArgumentException, IllegalAccessException {if (null == c || null ==value)return;//取消访问检查(私有成员变量的时候需要)
field.setAccessible(true);//给对象的成员变量赋值为指定的值--->value
field.set(c, value);
}
2.3 JsonArrayToList方法
public static ListJsonArrayToList(JSONArray ja) {
List ret = newArrayList();if (ja == null) {returnret;
}else{for(int i = 0; i < ja.length(); ++i) {try{
Object obj=ja.get(i);if (obj != null) {
ret.add(obj);
}
}catch(JSONException var4) {
;
}
}returnret;
}
}
3、将jsonArray转为list,注意参数json是jsonArray数据,原理类似,就不再多讲
public static List parseJsonArray2List(String json, Class extends T>aClass) {//反射获取所有public字段,包括父类
List list = null;
ListlistKey;try{
JSONArray array= newJSONArray(json);if (null ==array)returnlist;//获得自己的所有属性
Field[] fields =aClass.getFields();if (null ==fields)return null;
listKey= new ArrayList<>();for(Field field : fields) {
ValueHelper helper= newValueHelper();
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();
}returnlist;
}