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; }}
阅读全文
1 0
- Android--okhttp框架封装思路/网络请求组件的创建
- OKhttp网络请求组件的封装
- Android 的OkHttp 网络请求框架的学习封装
- 网络请求组件的封装思路
- Android中okhttp网络请求的封装
- okHttp网络请求框架get请求的封装
- Android封装OkHttp网络请求
- Android网络请求框架的使用okhttp
- 封装OkHttp的网络请求
- 完整的OKhttp请求封装的网络框架
- 安卓网络请求框架okHttp的使用与封装
- 简单实现RxJava2+Okhttp+Retrofit2的网络请求框架封装
- 简单封装okHttp网络请求框架
- 封装Retrofit + okhttp + rxjava网络请求框架
- OKHttp网络请求封装
- android网络访问框架OkHttp的进一步封装
- Android--menu和OkHttp框架(未封装),结合Executors(线程池)实现网络请求的案例
- OkHttp网络请求数据的封装
- Educational Codeforces Round 4 D The Union of k-Segments (扫描线)
- PAT B1015. 德才论
- 1019·两重for循环1(杨辉三角形)+两道练习题
- 欢迎使用CSDN-markdown编辑器
- 进程管理
- Android--okhttp框架封装思路/网络请求组件的创建
- [Leetcode] 308. Range Sum Query 2D
- LBG 矢量量化算法
- Oracle 树操作(select…start with…connect by…prior)
- Android studio加载工程慢,或连接超时
- 垃圾收集器与内存分配策略
- 647. Palindromic Substrings
- freeCalendar-自定义日历控件
- EXCEL排序 HDU