Java JSON解析工具类(支持泛型)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34033209/article/details/77806639

  我们在解析Json数据时,可能会遇到一些意想不到的麻烦,比如:如何支持泛型操作。针对这个问题,以鄙人的愚见及个人的工作经历,将自己在工作中写过的一个json解析工具类分享出来,公大家参考。

  该json解析工具类采用了阿里巴巴的开源项目fastjson,纵观json解析的开源项目及类库,似乎对fastjson的赞美从无停止过,fastjson更号称是Json解析中速度最快的一个类库。所以,能在项目中使用fastjson,能大大简化json解析难度,提高开发效率。

package com.hap.utils;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;


/**
* @author :wq
* @date : 2017年6月26日 下午5:15:51
* @version : v1.0
* @description :TODO
*/
public class ParseJson {


private ParseJson() {
}


public static <T> T[] parseJson(String jsonStr, Class<T> cls) {
// list集合,保存解析到的对象
List<T> list = new ArrayList<T>();


// 过滤空的串
if (jsonStr == null || jsonStr.equals("")) {
throw new RuntimeException("待解析的JSON串不能为空");
}


try {
// json对象
if (isJsonObject(jsonStr)) {
addReflectClassToList(jsonStr, cls, list);
// json数组
} else if (isJsonArray(jsonStr)) {
// 遍历jso数组获取json对象
JSONArray obj = JSON.parseArray(jsonStr);
for (Object os : obj) {
addReflectClassToList(os.toString(), cls, list);
}
}
} catch (Exception e) {
throw new RuntimeException("JSON解析异常");
}


// 创建T类型的新数组
@SuppressWarnings("unchecked")
T[] tArray = (T[]) Array.newInstance(cls, list.size());
// 为数组赋值
for (int i = 0, length = list.size(); i < length; i++) {
tArray[i] = list.get(i);
}


return tArray;
}


private static boolean isJsonArray(String jsonStr) {
return Pattern.matches("^\\{.*\\}$", jsonStr);
}


private static boolean isJsonObject(String jsonStr) {
return Pattern.matches("^\\[.*\\]$", jsonStr);
}


/**
* 将解析到的数据放入到集合中
*
* @param jsonStr
* 待解析的json串
* @param cls
* 运行时类的对象
* @param list
* list集合
* @throws IllegalAccessException
* @throws InstantiationException
*/
private static <T> void addReflectClassToList(String jsonStr, Class<T> cls, List<T> list)
throws InstantiationException, IllegalAccessException {
// 键 -- 字段
String field = null;
// 值-- 字段值
Object value = null;


// 创建运行时类的新实例
T t = cls.newInstance();


// 解析json
JSONObject jsonObject = JSON.parseObject(jsonStr);
for (Entry<String, Object> entry : jsonObject.entrySet()) {
// 返回与键
field = entry.getKey();
// 返回值
value = entry.getValue();
// 给实体字段设置数据
setFieldValueByName(field, value, t);
}


// 将对象添加进集合
list.add(t);
}


/**
* 给实体字段设置数据
*
* @param field
* 字段
* @param value
* 字段值
* @param obj
* 实体对象
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private static void setFieldValueByName(String fieldAttribute, Object fieldValue, Object obj)
throws IllegalArgumentException, IllegalAccessException {
Field field = getFieldNameByReflect(fieldAttribute, obj.getClass());


if (field != null) {
field.setAccessible(true);
Class<?> fieldType = field.getType();


// 根据字段类型给字段赋值
if (String.class == fieldType) {
field.set(obj, String.valueOf(fieldValue));
} else if (Integer.class == fieldType) {
field.set(obj, Integer.parseInt(fieldValue.toString()));
} else if ((Long.TYPE == fieldType) || Long.class == fieldType) {
field.set(obj, Long.valueOf(fieldValue.toString()));
} else if ((Float.TYPE == fieldType) || Float.class == fieldType) {
field.set(obj, Float.valueOf(fieldValue.toString()));
} else if ((Short.TYPE == fieldType) || Short.class == fieldType) {
field.set(obj, Short.valueOf(fieldValue.toString()));
} else if ((Double.TYPE == fieldType) || Double.class == fieldType) {
field.set(obj, Double.valueOf(fieldValue.toString()));
} else if (Character.TYPE == fieldType) {
if (fieldValue != null && fieldValue.toString().length() > 0) {
field.set(obj, Character.valueOf(fieldValue.toString().charAt(0)));
}
} else if (java.util.List.class == fieldType) {
// 返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型
Type genericType = field.getGenericType();
Class<?> clz = null;


// 泛型参数类型
if (genericType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericType;
// 获取泛型里面的class对象
clz = (Class<?>) pt.getActualTypeArguments()[0];
field.set(obj, Arrays.asList(parseJson(fieldValue.toString(), clz)));
}
}
} else {
throw new RuntimeException(obj.getClass().getSimpleName() + "未声明该字段");
}
}


/**
* 反射获取字段
*
* @param fieldAttribute
* @param class1
* @return
*/
private static Field getFieldNameByReflect(String fieldAttribute, Class<?> cls) {
// 获取当前类的所有信息
Field[] fields = cls.getFields();


// 若本类中存在该字段就返回
for (Field field : fields) {
if (field.getName().equals(fieldAttribute)) {
return field;
}
}


// 本类不存在,向上查找
Class<?> superclass = cls.getSuperclass();
if (superclass != null && superclass != Object.class) {
// 递归调用
getFieldNameByReflect(fieldAttribute, superclass);
}
return null;
}
}

这篇文章我加了大量的注释,之前也在百度文库中分享过,大家也可以去百度文库看看。如有不足之处,望各位不宁赐教。

猜你喜欢

转载自blog.csdn.net/qq_34033209/article/details/77806639