好久没有写博客了,一直很懒。
客户端和服务器数据交换时,现在最流行的是Json格式,因此我们常常需要去解析Json字符串成对象。手动解析工作量太大了,影响工作进度,也是一种体力活。我们可以用Gson工具包来解析,它是一种Json ORM,可以帮助我们把Json字符串解析成对象。可是gson-2.3.jar包230k大小,为了一个json解析功能导入如此大的jar包,怎么给自己的应用加分?
因此我自己写了一个工具类来替代gson,一切完美!
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Json工具类
* @author Davee
* @since 2015-10-30
*/
public class JsonUtil {
/**
* 解析json字符串至对象类型
* @param jsonStr Json格式字符串
* @param clazz 转换对象
* @return
*/
public static <T>T parseJson(String jsonStr, Class<T> clazz) {
T result = null;
if (clazz == null || jsonStr == null || jsonStr.length() == 0) {
return result;
}
try {
JSONObject jsonRoot = new JSONObject(jsonStr);
result = (T)clazz.newInstance();
recursion(result, clazz, jsonRoot);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private static <T> void recursion(T result, Class<?> clazz, JSONObject jsonRoot) {
if (jsonRoot == null) return;
try {
Field[] fields = clazz.getDeclaredFields();
if (fields != null) {
for (Field field : fields) {
setFieldValue(result, field, jsonRoot);
}
}
} catch (Exception e) {
e.printStackTrace();
}
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != Object.class) {//没有了父类
recursion(result, superClazz, jsonRoot);
}
}
private static void setFieldValue(Object obj, Field field, JSONObject json) {
field.setAccessible(true);
try {
if (field.getType().isPrimitive()) {
if (field.getType() == int.class) field.setInt(obj, json.optInt(field.getName()));
else if (field.getType() == long.class) field.setLong(obj, json.optLong(field.getName()));
else if (field.getType() == byte.class) field.setByte(obj, Byte.parseByte(json.optString(field.getName())));
else if (field.getType() == short.class) field.setShort(obj, Short.parseShort(json.optString(field.getName())));
else if (field.getType() == float.class) field.setFloat(obj, Float.parseFloat(json.optString(field.getName())));
else if (field.getType() == double.class) field.setDouble(obj, json.optDouble(field.getName()));
else if (field.getType() == char.class) {
String value = json.optString(field.getName());
if (value != null && value.length() > 0) field.setChar(obj, value.charAt(0));
}
else if (field.getType() == boolean.class) {
String value = json.optString(field.getName());
if (value == null || value.length() == 0
|| "false".equalsIgnoreCase(value)
|| "0".equals(value)
|| "NULL".equalsIgnoreCase(value)) field.setBoolean(obj, false);
else field.setBoolean(obj, true);
}
} else if (field.getType() == String.class) {
field.set(obj, json.optString(field.getName()));
} else if (field.getType() == java.util.Date.class || field.getType() == java.sql.Date.class) {
field.set(obj, DateFormatUtil.stringToDateTime(json.optString(field.getName())));
} else if (field.getType() == Integer.class) {
field.set(obj, json.optInt(field.getName()));
} else if (field.getType() == Long.class) {
field.set(obj, json.optLong(field.getName()));
} else if (field.getType() == Byte.class) {
field.set(obj, Byte.parseByte(json.optString(field.getName())));
} else if (field.getType() == Short.class) {
field.set(obj, Short.parseShort(json.optString(field.getName())));
} else if (field.getType() == Float.class) {
field.set(obj, Float.parseFloat(json.optString(field.getName())));
} else if (field.getType() == Double.class) {
field.set(obj, json.optDouble(field.getName()));
} else if (field.getType() == Character.class) {
String value = json.optString(field.getName());
if (value != null && value.length() > 0) field.set(obj, (Character)(value.charAt(0)));
} else if (field.getType() == Boolean.class) {
String value = json.optString(field.getName());
if (value == null || value.length() == 0
|| "false".equalsIgnoreCase(value)
|| "0".equals(value)
|| "NULL".equalsIgnoreCase(value)) field.set(obj, false);
else field.set(obj, true);
}
//非基本类型
else if (List.class.isAssignableFrom(field.getType())) {//field类型是否是List类或List子孙类
Type type = field.getGenericType();
if (type != null) {
if (type instanceof ParameterizedType) {
Class<?> genericClazz = (Class<?>)((ParameterizedType)type).getActualTypeArguments()[0];
JSONArray jsonArray = json.optJSONArray(field.getName());
if (jsonArray != null) {
List<Object> list = new ArrayList<Object>();
field.set(obj, list);
for (int i=0,size=jsonArray.length(); i<size; i++) {
if (genericClazz == String.class) {
list.add(jsonArray.optString(i));
} else if (genericClazz == java.util.Date.class || genericClazz == java.sql.Date.class) {
list.add(DateFormatUtil.stringToDateTime(json.optString(field.getName())));
} else if (genericClazz == Integer.class) {
list.add(json.optInt(field.getName()));
} else if (genericClazz == Long.class) {
list.add(json.optLong(field.getName()));
} else if (genericClazz == Byte.class) {
list.add(Byte.parseByte(json.optString(field.getName())));
} else if (genericClazz == Short.class) {
list.add(Short.parseShort(json.optString(field.getName())));
} else if (genericClazz == Float.class) {
list.add(Float.parseFloat(json.optString(field.getName())));
} else if (genericClazz == Double.class) {
list.add(json.optDouble(field.getName()));
} else if (genericClazz == Character.class) {
String value = json.optString(field.getName());
if (value != null && value.length() > 0) list.add((Character)(value.charAt(0)));
} else if (genericClazz == Boolean.class) {
String value = json.optString(field.getName());
if (value == null || value.length() == 0
|| "false".equalsIgnoreCase(value)
|| "0".equals(value)
|| "NULL".equalsIgnoreCase(value)) list.add(false);
else list.add(true);
} else {
Object childObj = genericClazz.newInstance();
list.add(childObj);
recursion(childObj, genericClazz, jsonArray.optJSONObject(i));
}
}
} else {
field.set(obj, null);
}
} else {
JSONArray jsonArray = json.optJSONArray(field.getName());
if (jsonArray != null) {
List<Object> list = new ArrayList<Object>();
field.set(obj, list);
for (int i=0,size=jsonArray.length(); i<size; i++) {
list.add(jsonArray.opt(i));
}
} else {
field.set(obj, null);
}
}
}
}
else {//自定义类型
Object childObj = field.getType().newInstance();
field.set(obj, childObj);
recursion(childObj, field.getType(), json.optJSONObject(field.getName()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}