前言:
前面两篇文章介绍了基于okHttp的post、get请求,以及文件的上传下载,今天主要介绍一下如何和Json解析一起使用?如何才能提高开发效率?
关于Json解析:
本文的Json解析采用阿里巴巴的FastJson 解析,也可以采用Gson解析,两者之间的对比请参考文章Android之json解析(FastJson Gson 对比)(http://www.cnblogs.com/whoislcj/p/5468420.html)。
关于泛型:
本文将采用json统一泛型解析,阅读本文之前请先对java泛型知识有一定的了解。
关于反射机制:
本文会采用Java的反射机制来解析泛型对象Class ,阅读本文之前请先对Java发射机制知识有一定的了解。
代码实现:
1.)首先我们声明一个TypeInfo.java类用来封装泛型相关属性
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class TypeInfo {
//Type泛型对象类型
private Class
componentType;
//Type所属对象类型
private Class
rawType;
//type
private Type type;
private TypeInfo(Class
rawType, Class
componentType) {
this.componentType = componentType;
this.rawType = rawType;
}
public static TypeInfo createArrayType(Class
componentType) {
return new TypeInfo(Array.class, componentType);
}
public static TypeInfo createNormalType(Class
componentType) {
return new TypeInfo(null, componentType);
}
public static TypeInfo createParameterizedType(Class
rawType, Class
componentType) {
return new TypeInfo(rawType, componentType);
}
public TypeInfo(Type type) {
this.type = type;
if (type instanceof ParameterizedType) {
//返回 Type 对象,表示声明此类型的类或接口。
this.rawType = (Class
) ((ParameterizedType) type).getRawType();
//getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
this.componentType = (Class
) actualTypeArguments[0];
// typeReference=new TypeReference
>(){};
} else if (type instanceof GenericArrayType) {
//返回 Type 对象,表示声明此类型的类或接口。
this.rawType = Array.class;
// 表示一种元素类型是参数化类型或者类型变量的数组类型
this.componentType = (Class
) ((GenericArrayType) type).getGenericComponentType();
} else {
this.componentType = (Class
) type;
}
}
public Type getType() {
return type;
}
public Class
getComponentType() {
return componentType;
}
public Class
getRawType() {
return rawType;
}
}
2.)声明ReqClassUtils.java类 用于通过反射机制获取泛型对象的TypeInfo
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class ReqClassUtils {
public static TypeInfo getCallbackGenericType(Class
clazz) {
//获得带有泛型的父类
Type genericSuperclass = clazz.getGenericSuperclass();//Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
TypeInfo type = getGetnericType(genericSuperclass);
if (type == null) {
Type[] genericInterfaces = clazz.getGenericInterfaces();
if (genericInterfaces != null && genericInterfaces.length > 0) {
type = getGetnericType(genericInterfaces[0]);
}
}
return type;
}
private static TypeInfo getGetnericType(Type type) {
if (type != null && type instanceof ParameterizedType) {
//getActualTypeArguments获取参数化类型的数组,泛型可能有多个
Type[] args = ((ParameterizedType) type).getActualTypeArguments();
if (args != null && args.length > 0) {
return new TypeInfo(args[0]);
}
}
return null;
}
}
3.)接下来重点来了,声明一个json解析工具类ReqJsonUtils.java,主要用于通过TypeInfo相关属性进行不同类型的json解析
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import static com.alibaba.fastjson.JSON.parseObject;
public class ReqJsonUtils {
//基本类型映射关系Map
private static final Map primitiveWrapperTypeMap = new HashMap(8);
static {
//添加基本类型
primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
primitiveWrapperTypeMap.put(Byte.class, byte.class);
primitiveWrapperTypeMap.put(Character.class, char.class);
primitiveWrapperTypeMap.put(Double.class, double.class);
primitiveWrapperTypeMap.put(Float.class, float.class);
primitiveWrapperTypeMap.put(Integer.class, int.class);
primitiveWrapperTypeMap.put(Long.class, long.class);
primitiveWrapperTypeMap.put(Short.class, short.class);
}
/**
* 将JSON字符串转换成指定的用户返回值类型
*
* @param type
* @param jsonData
* @return
* @throws JSONException
*/
public static
T parseHttpResult(TypeInfo type, String jsonData) throws JSONException { // 处理Void类型的返回值 if (Void.class.isAssignableFrom(type.getComponentType())) { return null; } //获取当前type的数据类型 Class
rawType = type.getRawType(); //是否是Array boolean isArray = rawType != null && Array.class.isAssignableFrom(rawType); //是否是Collection boolean isCollection = rawType != null && Collection.class.isAssignableFrom(rawType); //是否是Map boolean isMap = rawType != null && Map.class.isAssignableFrom(rawType); //获取泛型类型 Class
componentType = type.getComponentType(); //声明结果对象 T result = null; if (isCollection) {//处理collection result = (T) JSON.parseArray(jsonData, componentType); } else if (isArray) {//处理array result = (T) JSON.parseArray(jsonData, componentType).toArray(); } else if (isMap) {//处理Map result = (T) JSONObject.parseObject(jsonData, type.getType()); } else if (componentType.isAssignableFrom(String.class)) {//处理字符串返回值 return (T) jsonData; } else { // 接口的返回类型如果是简单类型,则会封装成为一个json对象,真正的对象存储在value属性上 if (isPrimitiveOrWrapper(componentType)) { result = (T) parseObject(jsonData); } else { //处理自定义对象 result = (T) parseObject(jsonData, componentType); } } return result; } /** * 判断是否是基本数据类型 * * @param clazz * @return */ public static boolean isPrimitiveOrWrapper(Class clazz) { return (clazz.isPrimitive() || isPrimitiveWrapper(clazz)); } /** * 判断是否是基本数据类型 * * @param clazz * @return */ public static boolean isPrimitiveWrapper(Class clazz) { return primitiveWrapperTypeMap.containsKey(clazz); } }
如何使用?
1.)实现解析
TypeInfo typeInfo = ReqClassUtils.getCallbackGenericType(callBack.getClass());
callBack.onReqSuccess(ReqJsonUtils.parseHttpResult(typeInfo, jsonData));
2.)发送请求
HashMap
paramsMap = new HashMap<>(); paramsMap.put("sourceType", "2"); paramsMap.put("sourceDesc", "[Android]" + Build.VERSION.RELEASE + "[Mobel]" + Build.BRAND + " " + Build.MODEL + Build.DEVICE); HashMap
params = dealStringBody(paramsMap); RequestManager.getInstance(this).requestAsyn("xxx/actionUrl", RequestManager.TYPE_POST_JSON, params, new ReqCallBack
() { @Override public void onReqSuccess(String result) { request_tv.setText(result); } @Override public void onReqFailed(String errorMsg) { } });
3.)支持类型
new ReqCallBack
>();//集合collection new ReqCallBack
>();//map new ReqCallBack
();//Void new ReqCallBack
();//基础类型
小结:如此一来发送请求到解析数据变得So easy !用流行的一句广告语来说的话,那就是老板再也不用担心我搞不定网络请求和json解析了。