原文地址:http://www.cnblogs.com/whoislcj/p/5533548.html

 前面两篇文章介绍了基于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解析了。


更多相关文章

  1. [置顶] Android(安卓)设置铃声分析
  2. Android(安卓)retrofit2+OkHttp3的初尝试
  3. Android(安卓)VideoView 循环播放视频
  4. Android知识体系总结之Android部分之Intent篇
  5. Android(安卓)用户界面---定制组件(Custom Components)(一)
  6. Android在标准linux基础上对休眠唤醒的实现
  7. android attr 属性 类型
  8. Android(安卓)自动化测试经验 - UiScrollable
  9. MTK Android(安卓)如何自动挂断电话

随机推荐

  1. Pull To Refresh for Android
  2. android从网上下载图片
  3. Android与服务器通信
  4. android之ID
  5. 毕设---android按钮事件
  6. Android(安卓)Fragment 简洁版 list
  7. android每隔5s显示时间
  8. android ScrollView 多张图片之间有空白
  9. android监听edittext输入事件
  10. android studio 复制项目