Android--okhttp框架封装思路/网络请求组件的创建

来源:互联网 发布:js中string转list 编辑:程序博客网 时间:2024/06/05 07:20

封装目的

规避okhttp框架API更新带来的风险

提高代码复用性

提升程序的可扩展性


封装逻辑

封装逻辑

封装思路

封装思路--思维导图

1.封装request

RequestParams类    封装所有的请求参数到HashMap中(线程安全)CommonRequest类    接受请求参数,生成request对象

RequestParams类

    封装所有的请求参数到HashMap中(线程安全)
import java.io.FileNotFoundException;import java.util.HashMap;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/** * @author xiaoxu 17-07-21 * @function 封装所有的请求参数到HashMap中(线程安全) */public class RequestParams {    public ConcurrentHashMap<String, String> urlParams = new ConcurrentHashMap<String, String>();    public ConcurrentHashMap<String, Object> fileParams = new ConcurrentHashMap<String, Object>();    /**     * Constructs a new empty {@code RequestParams} instance.     */    public RequestParams() {        this((Map<String, String>) null);    }    /**     * Constructs a new RequestParams instance containing the key/value string     * params from the specified map.     *     * @param source the source key/value string map to add.     */    public RequestParams(Map<String, String> source) {        if (source != null) {            for (Map.Entry<String, String> entry : source.entrySet()) {                put(entry.getKey(), entry.getValue());            }        }    }    /**     * Constructs a new RequestParams instance and populate it with a single     * initial key/value string param.     *     * @param key   the key name for the intial param.     * @param value the value string for the initial param.     */    public RequestParams(final String key, final String value) {        this(new HashMap<String, String>() {            {                put(key, value);            }        });    }    /**     * Adds a key/value string pair to the request.     *     * @param key   the key name for the new param.     * @param value the value string for the new param.     */    public void put(String key, String value) {        if (key != null && value != null) {            urlParams.put(key, value);        }    }    public void put(String key, Object object) throws FileNotFoundException {        if (key != null) {            fileParams.put(key, object);        }    }    public boolean hasParams() {        if(urlParams.size() > 0 || fileParams.size() > 0){            return true;        }        return false;    }}

CommonRequest类

    接受请求参数,生成request对象
import java.util.Map;import okhttp3.FormBody;import okhttp3.Request;/** * Created by xiaoxu on 2017/7/22. * * @function 接受请求参数,生成request对象 */public class CommonRequest {    /**     * @param url     * @param params     * @return 返回一个创建好的post类型request对象     */    public static Request createPostRequest(String url, RequestParams params) {        //获取构建者        FormBody.Builder mFormBodyBuilder = new FormBody.Builder();        if (params != null) {            for (Map.Entry<String, String> entry : params.urlParams.entrySet()) {                //将请求参数遍历添加到请求构建类中                mFormBodyBuilder.add(entry.getKey(), entry.getValue());            }        }        //通过请求构建类的build方法获取到真正的【请求体】对象        FormBody mFromBody = mFormBodyBuilder.build();        return new Request.Builder().url(url).post(mFromBody).build();    }    /**     * @param url     * @param params     * @return 返回一个get类型请求对象     */    public static Request createGetRequest(String url, RequestParams params) {        //StringBuilder 效率更高        StringBuilder urlBuilder = new StringBuilder(url).append("?");        if (params != null) {            for (Map.Entry<String, String> entry : params.urlParams.entrySet()) {                //将请求参数遍历添拼接到url中                urlBuilder.append(entry.getKey())                        .append("=")                        .append(entry.getValue())                        .append("&");            }        }        return new Request.Builder()                .url(urlBuilder.substring(0, urlBuilder.length() - 1))                .get()                .build();    }}

2.封装client

CommonOkthhpClient类    请求体发送,请求参数的配置,https的支持
import com.yingyuliuliwan.liuliwansdk.okhttps.https.HttpsUtils;import com.yingyuliuliwan.liuliwansdk.okhttps.response.CommonJsonCallback;import java.util.concurrent.TimeUnit;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.SSLSession;import okhttp3.Call;import okhttp3.OkHttpClient;import okhttp3.Request;/** * Created by xiaoxu on 2017/7/22. * * @function 请求体发送,请求参数的配置,https的支持 */public class CommonOkthhpClient {    private static final int TIME_OUT = 30000;    private static OkHttpClient mOkHttpClient;    //使用静态代码块设置请求参数,保证mOkHttpClient对象所有实例的参数都一致    static {        //client对象的构建者        OkHttpClient.Builder okhttpBulider = new OkHttpClient.Builder();        //为构建者他填充超时时间        okhttpBulider.connectTimeout(TIME_OUT, TimeUnit.SECONDS);        okhttpBulider.readTimeout(TIME_OUT, TimeUnit.SECONDS);        okhttpBulider.writeTimeout(TIME_OUT, TimeUnit.SECONDS);        okhttpBulider.followRedirects(true);        //添加https支持(表示客户端支持所有类型证书的的https请求)        okhttpBulider.hostnameVerifier(new HostnameVerifier() {            @Override            public boolean verify(String hostname, SSLSession session) {                //无论主机名是什么都返回true                return true;            }        });        okhttpBulider.sslSocketFactory(HttpsUtils.initSSLSocketFactory());        //生成client对象        mOkHttpClient = okhttpBulider.build();    }    public static Call sendRequest(Request request, CommonJsonCallback commonCallBack){        Call call = mOkHttpClient.newCall(request);        call.enqueue(commonCallBack);        return call;    }}

3.封装response

DisposeDataListener类    自定义监听事件,回调事件处理DisposeDataHandle类    将回调监听对象和要转化的字节码进行封装CommonJsonCallback类    处理json的回调响应ResponseEntityToModule类    将json对象转化为实体类对象(也可以使用第三方库)

DisposeDataListener类

    自定义监听事件,回调事件处理
/** * Created by xiaoxu on 2017/7/23. * 添加事件监听(防止框架回调API的改变,增加扩展性) */public interface DisposeDataListener {    /**     * 请求成功回调事件处理     */    public void onSuccess(Object responseObj);    /**     * 请求失败回调事件处理     */    public void onFailure(Object reasonObj);}

DisposeDataHandle类

    将回调监听对象和要转化的字节码进行封装
/** * Created by Administrator on 2017/7/23. *  将回调监听对象和要转化的字节码进行封装 */public class DisposeDataHandle {    public DisposeDataListener mListener = null;    public Class<?> mClass = null;    public DisposeDataHandle(DisposeDataListener mListener) {        this.mListener = mListener;    }    public DisposeDataHandle(Class<?> mClass, DisposeDataListener mListener) {        this.mClass = mClass;        this.mListener = mListener;    }}

CommonJsonCallback类

    处理json的回调响应,返回callBack对象
import android.os.Handler;import android.os.Looper;import com.yingyuliuliwan.liuliwansdk.adutil.ResponseEntityToModule;import com.yingyuliuliwan.liuliwansdk.okhttps.exception.OkHttpException;import com.yingyuliuliwan.liuliwansdk.okhttps.listener.DisposeDataHandle;import com.yingyuliuliwan.liuliwansdk.okhttps.listener.DisposeDataListener;import org.json.JSONObject;import java.io.IOException;import java.util.ArrayList;import okhttp3.Call;import okhttp3.Callback;import okhttp3.Headers;import okhttp3.Response;/** * Created by xiaoxu on 2017/7/23. */public class CommonJsonCallback implements Callback {    //与服务器返回的字段的一个关系    protected final String RESULT_CODE = "ecode"; // 有返回则对于http请求来说是成功的,但还有可能是业务逻辑上的错误    protected final int RESULT_CODE_VALUE = 0;    protected final String ERROR_MSG = "emsg";    protected final String EMPTY_MSG = "";    protected final String COOKIE_STORE = "Set-Cookie"; // decide the server it    // can has the value of    // set-cookie2    /**     * 自定义异常类型     */    protected final int NETWORK_ERROR = -1; // the network relative error    protected final int JSON_ERROR = -2; // the JSON relative error    protected final int OTHER_ERROR = -3; // the unknow error    /**     * 将其它线程的数据转发到UI线程     */    private Handler mDeliveryHandler;    private DisposeDataListener mListener;    private Class<?> mClass;    public CommonJsonCallback(DisposeDataHandle handle) {        this.mListener = handle.mListener;        this.mClass = handle.mClass;        this.mDeliveryHandler = new Handler(Looper.getMainLooper());    }    //请求失败处理    @Override    public void onFailure(final Call call, final IOException ioexception) {        /**         * 此时还在非UI线程,因此要转发         */        mDeliveryHandler.post(new Runnable() {            @Override            public void run() {                mListener.onFailure(new OkHttpException(NETWORK_ERROR, ioexception));            }        });    }    //真正的响应处理函数    @Override    public void onResponse(final Call call, final Response response) throws IOException {        //获取返回的字符串        final String result = response.body().string();        final ArrayList<String> cookieLists = handleCookie(response.headers());        //将字符串转发给主线程        mDeliveryHandler.post(new Runnable() {            @Override            public void run() {                handleResponse(result);                /**后续升级准备                 * handle the cookie                 */                /*if (mListener instanceof DisposeHandleCookieListener) {                    ((DisposeHandleCookieListener) mListener).onCookie(cookieLists);                }*/            }        });    }   /* private ArrayList<String> handleCookie(Headers headers) {        ArrayList<String> tempList = new ArrayList<String>();        for (int i = 0; i < headers.size(); i++) {            if (headers.name(i).equalsIgnoreCase(COOKIE_STORE)) {                tempList.add(headers.value(i));            }        }        return tempList;    }*/    //处理服务器返回的响应数据    private void handleResponse(Object responseObj) {        //为了保障代码的健壮性,进行判空处理        if (responseObj == null || responseObj.toString().trim().equals("")) {            mListener.onFailure(new OkHttpException(NETWORK_ERROR, EMPTY_MSG));            return;        }        try {             /*            * 协议确定后看这里如何修改            */            JSONObject result = new JSONObject(responseObj.toString());            //判断http请求是否成功            if (result.has(RESULT_CODE)){                //从json数据中获取响应码,是否为定义的正常的响应码                if (result.getInt(RESULT_CODE)==RESULT_CODE_VALUE){                    if (mClass == null) {                        //不需要转化为实体对象,直接返回数据到应用层                        mListener.onSuccess(result);                    } else {                        // 需要将json对象转化为实体类对象(自己创建的,也可以使用第三方库)                        Object obj = ResponseEntityToModule.parseJsonObjectToModule(result, mClass);                        //判断是否正确的转化为实体类对象                        if (obj != null) {                            mListener.onSuccess(obj);                        } else {                            //返回的是一个不合法的json                            mListener.onFailure(new OkHttpException(JSON_ERROR, EMPTY_MSG));                        }                    }                }            }        } catch (Exception e) {            mListener.onFailure(new OkHttpException(OTHER_ERROR, e.getMessage()));            e.printStackTrace();        }    }}

ResponseEntityToModule类

    将json对象转化为实体类对象(也可以使用第三方库)
import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.lang.reflect.Field;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.ArrayList;import io.realm.RealmList;import io.realm.RealmModel;import io.realm.RealmObject;/********************************************************** * @文件名称:ResponseEntityToModule.java * @文件作者:qndroid * @创建时间:2015年7月31日 上午10:51:44 * @文件描述:递归ORM映射(有反射,不能被混淆) * @修改历史:2015年7月31日创建初始版本 **********************************************************/public class ResponseEntityToModule {    public static Object parseJsonToModule(String jsonContent, Class<?> clazz) {        Object moduleObj = null;        try {            JSONObject jsonObj = new JSONObject(jsonContent);            moduleObj = parseJsonObjectToModule(jsonObj, clazz);        } catch (JSONException e) {            e.printStackTrace();        }        return moduleObj;    }    public static Object parseJsonObjectToModule(JSONObject jsonObj, Class<?> clazz) {        Object moduleObj = null;        try {            moduleObj = (Object) clazz.newInstance();            setFieldValue(moduleObj, jsonObj, clazz);        } catch (IllegalArgumentException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (JSONException e) {            e.printStackTrace();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        }        return moduleObj;    }    public static RealmObject parseJsonObjectToRealmModel(JSONObject jsonObj, Class<?> clazz) {        RealmObject moduleObj = null;        try {            moduleObj = (RealmObject) clazz.newInstance();            setFieldValue(moduleObj, jsonObj, clazz);        } catch (IllegalArgumentException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (JSONException e) {            e.printStackTrace();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        }        return moduleObj;    }    private static void setFieldValue(Object moduleObj, JSONObject jsonObj, Class<?> clazz)            throws IllegalArgumentException, IllegalAccessException, JSONException, InstantiationException {        if (clazz.getSuperclass() != null) {            setFieldValue(moduleObj, jsonObj, clazz.getSuperclass());        }        Field[] fields = clazz.getDeclaredFields();        Class<?> cls;        String name;        for (Field f : fields) {            f.setAccessible(true);            cls = f.getType();            name = f.getName();            if (!jsonObj.has(name) || jsonObj.isNull(name)) {                continue;            }            if (cls.isPrimitive() || isWrappedPrimitive(cls))            {                setPrimitiveFieldValue(f, moduleObj, jsonObj.get(name));            } else {                if (cls.isAssignableFrom(String.class)) {                    f.set(moduleObj, String.valueOf(jsonObj.get(name)));                } else if (cls.isAssignableFrom(ArrayList.class)) {                    parseJsonArrayToList(f, name, moduleObj, jsonObj);                }                //在这儿可以加个判断,如果是RealmList类型则转化为RealmList,方便直接存入数据库                else if (cls.isAssignableFrom(RealmList.class)) {                    parseJsonArrayToRealmList(f, name, moduleObj, jsonObj);                } else {                    Object obj = parseJsonObjectToModule(jsonObj.getJSONObject(name), cls.newInstance().getClass());                    f.set(moduleObj, obj);                }            }        }    }    private static RealmList<RealmObject> parseJsonArrayToRealmList(Field field, String fieldName, Object moduleObj,                                                                   JSONObject jsonObj) throws JSONException, IllegalArgumentException, IllegalAccessException {        RealmList<RealmObject> objList = new RealmList<>();        Type fc = field.getGenericType();        if (fc instanceof ParameterizedType)        {            ParameterizedType pt = (ParameterizedType) fc;            if (pt.getActualTypeArguments()[0] instanceof Class)            {                Class<?> clss = (Class<?>) pt.getActualTypeArguments()[0];                if (jsonObj.get(fieldName) instanceof JSONArray) {                    JSONArray array = jsonObj.getJSONArray(fieldName);                    for (int i = 0; i < array.length(); i++) {                        if (array.get(i) instanceof JSONObject) {                            objList.add(parseJsonObjectToRealmModel(array.getJSONObject(i), clss));                        } else {                            if (clss.isAssignableFrom(array.get(i).getClass())) {                                objList.add((RealmObject) array.get(i));                            }                        }                    }                }                field.set(moduleObj, objList);            }        }        return objList;    }    private static ArrayList<Object> parseJsonArrayToList(Field field, String fieldName, Object moduleObj,                                                          JSONObject jsonObj) throws JSONException, IllegalArgumentException, IllegalAccessException {        ArrayList<Object> objList = new ArrayList<Object>();        Type fc = field.getGenericType();        if (fc instanceof ParameterizedType)        {            ParameterizedType pt = (ParameterizedType) fc;            if (pt.getActualTypeArguments()[0] instanceof Class)            {                Class<?> clss = (Class<?>) pt.getActualTypeArguments()[0];                if (jsonObj.get(fieldName) instanceof JSONArray) {                    JSONArray array = jsonObj.getJSONArray(fieldName);                    for (int i = 0; i < array.length(); i++) {                        if (array.get(i) instanceof JSONObject) {                            objList.add(parseJsonObjectToModule(array.getJSONObject(i), clss));                        } else {                            if (clss.isAssignableFrom(array.get(i).getClass())) {                                objList.add(array.get(i));                            }                        }                    }                }                field.set(moduleObj, objList);            }        }        return objList;    }    private static void setPrimitiveFieldValue(Field field, Object moduleObj, Object jsonObj)            throws IllegalArgumentException, IllegalAccessException {        if (field.getType().isAssignableFrom(jsonObj.getClass())) {            field.set(moduleObj, jsonObj);        } else {            field.set(moduleObj, makeTypeSafeValue(field.getType(), jsonObj.toString()));        }    }    private static final Object makeTypeSafeValue(Class<?> type, String value) throws NumberFormatException,            IllegalArgumentException {        if (int.class == type || Integer.class == type) {            return Integer.parseInt(value);        } else if (long.class == type || Long.class == type) {            return Long.parseLong(value);        } else if (short.class == type || Short.class == type) {            return Short.parseShort(value);        } else if (char.class == type || Character.class == type) {            return value.charAt(0);        } else if (byte.class == type || Byte.class == type) {            return Byte.valueOf(value);        } else if (float.class == type || Float.class == type) {            return Float.parseFloat(value);        } else if (double.class == type || Double.class == type) {            return Double.parseDouble(value);        } else if (boolean.class == type || Boolean.class == type) {            return Boolean.valueOf(value);        } else {            return value;        }    }    private static boolean isWrappedPrimitive(Class<?> type) {        if (type.getName().equals(Boolean.class.getName()) || type.getName().equals(Byte.class.getName())                || type.getName().equals(Character.class.getName()) || type.getName().equals(Short.class.getName())                || type.getName().equals(Integer.class.getName()) || type.getName().equals(Long.class.getName())                || type.getName().equals(Float.class.getName()) || type.getName().equals(Double.class.getName())) {            return true;        }        return false;    }}

原创粉丝点击