【cookie】代表請求的用戶身份;java
【須要實現的抽象類】android
【實現抽象類-1】formBody只能上傳簡單的key-value數據;發送post請求的時候會構建formBody;json
【實現抽象類-2】MultipartBody:能夠實現對象類型的數據的上傳;大的文件的上傳;服務器
【request類】cookie
【call】網絡
【realCall】session
【Header類】app
【DNS解析域名的類】框架
【connection相關類】ide
【CallBack】返回數據的回調;
【address封裝了請求的數據】
【Cache模塊】
【核心類】核心的方法:sendRequest;
【dispatcher分發類】
【流程】dispatcher將call數據放到隊列中,在隊列中依次執行Call,realCall對調用httpEngine,真正的構建connection和request,而後調用connect方法,獲取最終的response;封裝在respBody中,
而後在CallBack的onresponse方法中獲取數據;
【okhttpClient類】全部流程的相互配合使用的是okhttpClient類進行配合的
【回調方法】定義本次的請求的處理會有哪些回調的方法進行處理;
【DisposeDataHandle.java】G:\CommonLibrary-master\CommonHttpLibrary\src\com\okhttp\listener\DisposeDataHandle.java
1 package com.okhttp.listener; 2 3 /** 4 * 5 * 6 */ 7 public class DisposeDataHandle 8 { 9 public DisposeDataListener mListener = null; //response的響應回調; 10 public Class<?> mClass = null; //對應的json字節碼文件 11 public String mSource = null; 12 13 //直接將獲得的json字符串拋到應用層解析; 14 public DisposeDataHandle(DisposeDataListener listener) 15 { 16 this.mListener = listener; 17 } 18 19 //若是傳遞了對象,就將json文件轉化爲該對象的文件; 20 public DisposeDataHandle(DisposeDataListener listener, Class<?> clazz) 21 { 22 this.mListener = listener; 23 this.mClass = clazz; 24 } 25 26 public DisposeDataHandle(DisposeDataListener listener, String source) 27 { 28 this.mListener = listener; 29 this.mSource = source; 30 } 31 }
【封轉的請求參數】以鍵值對的形式進行封裝;G:\CommonLibrary-master\CommonHttpLibrary\src\com\okhttp\request\RequestParams.java
1 package com.okhttp.request; 2 3 import java.io.FileNotFoundException; 4 import java.util.HashMap; 5 import java.util.Map; 6 import java.util.concurrent.ConcurrentHashMap; 7 8 public class RequestParams { 9 10 public ConcurrentHashMap<String, String> urlParams = new ConcurrentHashMap<String, String>(); 11 public ConcurrentHashMap<String, Object> fileParams = new ConcurrentHashMap<String, Object>(); 12 13 /** 14 * Constructs a new empty {@code RequestParams} instance. 15 */ 16 public RequestParams() { 17 this((Map<String, String>) null); 18 } 19 20 /** 21 * Constructs a new RequestParams instance containing the key/value string 22 * params from the specified map. 23 * 24 * @param source 25 * the source key/value string map to add. 26 */ 27 public RequestParams(Map<String, String> source) { 28 if (source != null) { 29 for (Map.Entry<String, String> entry : source.entrySet()) { 30 put(entry.getKey(), entry.getValue()); 31 } 32 } 33 } 34 35 /** 36 * Constructs a new RequestParams instance and populate it with a single 37 * initial key/value string param. 38 * 39 * @param key 40 * the key name for the intial param. 41 * @param value 42 * the value string for the initial param. 43 */ 44 public RequestParams(final String key, final String value) { 45 this(new HashMap<String, String>() { 46 { 47 put(key, value); 48 } 49 }); 50 } 51 52 /** 53 * Adds a key/value string pair to the request. 54 * 55 * @param key 56 * the key name for the new param. 57 * @param value 58 * the value string for the new param. 59 */ 60 public void put(String key, String value) { 61 if (key != null && value != null) { 62 urlParams.put(key, value); 63 } 64 } 65 66 public void put(String key, Object object) throws FileNotFoundException { 67 68 if (key != null) { 69 fileParams.put(key, object); 70 } 71 } 72 }
【封裝請求】G:\CommonLibrary-master\CommonHttpLibrary\src\com\okhttp\request\CommonRequest.java
[post請求]
[文件上傳請求]
[源碼]G:\CommonLibrary-master\CommonHttpLibrary\src\com\okhttp\request\CommonRequest.java
1 package com.okhttp.request; 2 3 import java.io.File; 4 import java.util.Map; 5 6 import okhttp3.FormBody; 7 import okhttp3.Headers; 8 import okhttp3.MediaType; 9 import okhttp3.MultipartBody; 10 import okhttp3.Request; 11 import okhttp3.RequestBody; 12 13 /** 14 * @author vision 15 * @function build the request 16 * 主要負責對各類請求的文件類型的封裝:get/post/上傳文件類型/下載文件類型; 17 */ 18 public class CommonRequest { 19 20 /** 21 * create the key-value Request 22 * 23 * @function: 將 params拼接在url後面,而後構成Request請求; 24 */ 25 public static Request createPostRequest(String url, RequestParams params) { 26 FormBody.Builder mFormBodyBuild = new FormBody.Builder(); 27 if (params != null) { 28 for (Map.Entry<String, String> entry : params.urlParams.entrySet()) { 29 mFormBodyBuild.add(entry.getKey(), entry.getValue()); 30 } 31 } 32 FormBody mFormBody = mFormBodyBuild.build(); 33 return new Request.Builder().url(url).post(mFormBody).build(); 34 } 35 36 /** 37 * ressemble the params to the url 38 * 39 * @param url 40 * @param params 41 * @return 42 * @function:建立一個post請求的request請求類型的對象; 43 */ 44 public static Request createGetRequest(String url, RequestParams params) { 45 StringBuilder urlBuilder = new StringBuilder(url).append("?"); 46 if (params != null) { 47 for (Map.Entry<String, String> entry : params.urlParams.entrySet()) { 48 urlBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); 49 } 50 } 51 return new Request.Builder().url(urlBuilder.substring(0, urlBuilder.length() - 1)).get().build(); 52 } 53 54 /** 55 * 文件上傳請求 56 * 57 * @return 58 */ 59 private static final MediaType FILE_TYPE = MediaType.parse("application/octet-stream"); 60 61 public static Request createMultiPostRequest(String url, RequestParams params) { 62 63 MultipartBody.Builder requestBody = new MultipartBody.Builder(); 64 requestBody.setType(MultipartBody.FORM); 65 if (params != null) { 66 67 for (Map.Entry<String, Object> entry : params.fileParams.entrySet()) { 68 //判斷是不是文件; 69 if (entry.getValue() instanceof File) { 70 //若是是文件; 71 requestBody.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + entry.getKey() + "\""), 72 RequestBody.create(FILE_TYPE, (File) entry.getValue())); 73 } else if (entry.getValue() instanceof String) { 74 //若是不是文件,就當作簡單的key-value值建立; 75 requestBody.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + entry.getKey() + "\""), 76 RequestBody.create(null, (String) entry.getValue())); 77 } 78 } 79 } 80 return new Request.Builder().url(url).post(requestBody.build()).build(); 81 } 82 }
【回調的封裝】實現callBack接口;
【CommonJsonCallback.java】對json的回調的處理;G:\CommonLibrary-master\CommonHttpLibrary\src\com\okhttp\response\CommonJsonCallback.java
1 package com.okhttp.response; 2 3 import java.io.IOException; 4 import java.util.ArrayList; 5 6 import org.json.JSONObject; 7 8 import com.loopj.android.http.commonhttp.ResponseEntityToModule; 9 import com.okhttp.exception.OkHttpException; 10 import com.okhttp.listener.DisposeDataHandle; 11 import com.okhttp.listener.DisposeDataListener; 12 import com.okhttp.listener.DisposeHandleCookieListener; 13 14 import android.os.Handler; 15 import android.os.Looper; 16 import okhttp3.Call; 17 import okhttp3.Callback; 18 import okhttp3.Headers; 19 import okhttp3.Response; 20 21 /** 22 * @author vision 23 * @function 專門處理JSON的回調 24 */ 25 public class CommonJsonCallback implements Callback { 26 27 /** 28 * the logic layer exception, may alter in different app 29 * 【注意】此段代碼是根據公司的服務器的協議進行定製的;不一樣公司不一致; 30 */ 31 // 有返回則對於http請求來講是成功的,但還有多是業務邏輯上的錯誤 32 protected final String RESULT_CODE = "ecode"; 33 protected final int RESULT_CODE_VALUE = 0; 34 protected final String ERROR_MSG = "emsg"; 35 protected final String EMPTY_MSG = ""; 36 protected final String COOKIE_STORE = "Set-Cookie"; // decide the server it 37 // can has the value of 38 // set-cookie2 39 40 /** 41 * the java layer exception, do not same to the logic error 42 */ 43 protected final int NETWORK_ERROR = -1; // the network relative error 44 protected final int JSON_ERROR = -2; // the JSON relative error 45 protected final int OTHER_ERROR = -3; // the unknow error 46 47 /** 48 * 將其它線程的數據轉發到UI線程 49 */ 50 private Handler mDeliveryHandler; //數據的轉發 51 private DisposeDataListener mListener; //接口; 52 private Class<?> mClass; //要轉化爲的字符串的數據; 53 54 public CommonJsonCallback(DisposeDataHandle handle) { 55 this.mListener = handle.mListener; 56 this.mClass = handle.mClass; 57 //須要返回到主線程中,所以須要建立主線程的Looper; 58 this.mDeliveryHandler = new Handler(Looper.getMainLooper()); 59 } 60 61 //對返回數據的失敗的處理 62 @Override 63 public void onFailure(final Call call, final IOException ioexception) { 64 /** 65 * 此時還在非UI線程,所以要轉發 66 */ 67 mDeliveryHandler.post(new Runnable() { 68 @Override 69 public void run() { 70 //直接回調listener中的onFailure便可; 71 mListener.onFailure(new OkHttpException(NETWORK_ERROR, ioexception)); 72 } 73 }); 74 } 75 76 77 @Override 78 public void onResponse(final Call call, final Response response) throws IOException { 79 final String result = response.body().string(); 80 final ArrayList<String> cookieLists = handleCookie(response.headers()); 81 mDeliveryHandler.post(new Runnable() { 82 @Override 83 public void run() { 84 handleResponse(result); //見105行的方法的處理; 85 /** 86 * handle the cookie 87 */ 88 if (mListener instanceof DisposeHandleCookieListener) { 89 ((DisposeHandleCookieListener) mListener).onCookie(cookieLists); 90 } 91 } 92 }); 93 } 94 95 private ArrayList<String> handleCookie(Headers headers) { 96 ArrayList<String> tempList = new ArrayList<String>(); 97 for (int i = 0; i < headers.size(); i++) { 98 if (headers.name(i).equalsIgnoreCase(COOKIE_STORE)) { 99 tempList.add(headers.value(i)); 100 } 101 } 102 return tempList; 103 } 104 105 private void handleResponse(Object responseObj) { 106 if (responseObj == null) { 107 mListener.onFailure(new OkHttpException(NETWORK_ERROR, EMPTY_MSG)); 108 return; 109 } 110 111 try { 112 JSONObject result = new JSONObject(responseObj.toString()); 113 if (result.has(RESULT_CODE)) { 114 if (result.optInt(RESULT_CODE) == RESULT_CODE_VALUE) { 115 //若是沒有傳入返回的對象; 116 if (mClass == null) { 117 //直接返回到應用層; 118 mListener.onSuccess(result); 119 } else { 120 //對json字符串進行解析; 121 Object obj = ResponseEntityToModule.parseJsonObjectToModule(result, mClass); 122 if (obj != null) { 123 //json數據解析成功,返回給應用層; 124 mListener.onSuccess(obj); 125 } else { 126 //解析失敗,拋出異常; 127 mListener.onFailure(new OkHttpException(JSON_ERROR, EMPTY_MSG)); 128 } 129 } 130 } else { 131 if (result.has(ERROR_MSG)) { 132 mListener.onFailure( 133 new OkHttpException(result.optInt(RESULT_CODE), result.optString(ERROR_MSG))); 134 } else { 135 mListener.onFailure(new OkHttpException(result.optInt(RESULT_CODE), EMPTY_MSG)); 136 } 137 } 138 } else { 139 if (result.has(ERROR_MSG)) { 140 mListener.onFailure(new OkHttpException(OTHER_ERROR, result.optString(ERROR_MSG))); 141 } 142 } 143 } catch (Exception e) { 144 mListener.onFailure(new OkHttpException(OTHER_ERROR, e.getMessage())); 145 e.printStackTrace(); 146 } 147 } 148 }
【對文件的解析的回調的處理】
1 package com.okhttp.response; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 8 import com.okhttp.exception.OkHttpException; 9 import com.okhttp.listener.DisposeDataHandle; 10 import com.okhttp.listener.DisposeDownloadListener; 11 12 import android.os.Handler; 13 import android.os.Looper; 14 import android.os.Message; 15 import okhttp3.Call; 16 import okhttp3.Callback; 17 import okhttp3.Response; 18 19 /********************************************************** 20 * @文件名稱:CommonFileCallback.java 23 * @文件描述:專門處理文件下載回調 24 * @修改歷史:2016年1月23日建立初始版本 25 **********************************************************/ 26 public class CommonFileCallback implements Callback { 27 /** 28 * the java layer exception, do not same to the logic error 29 */ 30 protected final int NETWORK_ERROR = -1; // the network relative error 31 protected final int IO_ERROR = -2; // the JSON relative error 32 protected final String EMPTY_MSG = ""; 33 /** 34 * 將其它線程的數據轉發到UI線程 35 */ 36 private static final int PROGRESS_MESSAGE = 0x01; 37 private Handler mDeliveryHandler; 38 private DisposeDownloadListener mListener; 39 private String mFilePath; 40 private int mProgress; 41 42 public CommonFileCallback(DisposeDataHandle handle) { 43 this.mListener = (DisposeDownloadListener) handle.mListener; 44 this.mFilePath = handle.mSource; 45 this.mDeliveryHandler = new Handler(Looper.getMainLooper()) { 46 @Override 47 public void handleMessage(Message msg) { 48 switch (msg.what) { 49 case PROGRESS_MESSAGE: 50 mListener.onProgress((int) msg.obj); 51 break; 52 } 53 } 54 }; 55 } 56 57 @Override 58 public void onFailure(final Call call, final IOException ioexception) { 59 mDeliveryHandler.post(new Runnable() { 60 @Override 61 public void run() { 62 mListener.onFailure(new OkHttpException(NETWORK_ERROR, ioexception)); 63 } 64 }); 65 } 66 67 @Override 68 public void onResponse(Call call, Response response) throws IOException { 69 final File file = handleResponse(response); 70 mDeliveryHandler.post(new Runnable() { 71 @Override 72 public void run() { 73 if (file != null) { 74 mListener.onSuccess(file); 75 } else { 76 mListener.onFailure(new OkHttpException(IO_ERROR, EMPTY_MSG)); 77 } 78 } 79 }); 80 } 81 82 /** 83 * 此時還在子線程中,不則調用回調接口 84 * 85 * @param response 86 * @return 87 */ 88 private File handleResponse(Response response) { 89 if (response == null) { 90 return null; 91 } 92 93 InputStream inputStream = null; 94 File file = null; 95 FileOutputStream fos = null; 96 byte[] buffer = new byte[2048]; 97 int length = -1; 98 int currentLength = 0; 99 double sumLength = 0; 100 try { 101 file = new File(mFilePath); 102 fos = new FileOutputStream(file); 103 inputStream = response.body().byteStream(); 104 sumLength = (double) response.body().contentLength(); 105 106 while ((length = inputStream.read(buffer)) != -1) { 107 fos.write(buffer, 0, length); 108 currentLength += length; 109 mProgress = (int) (currentLength / sumLength * 100); 110 mDeliveryHandler.obtainMessage(PROGRESS_MESSAGE, mProgress).sendToTarget(); 111 } 112 fos.flush(); 113 } catch (Exception e) { 114 file = null; 115 } finally { 116 try { 117 fos.close(); 118 inputStream.close(); 119 } catch (IOException e) { 120 e.printStackTrace(); 121 } 122 } 123 return file; 124 } 125 }
【client的封裝】對整個流程的調用
1 package com.okhttp; 2 3 import java.io.InputStream; 4 import java.util.concurrent.TimeUnit; 5 6 import javax.net.ssl.HostnameVerifier; 7 import javax.net.ssl.SSLSession; 8 9 import okhttp3.Call; 10 import okhttp3.OkHttpClient; 11 import okhttp3.Request; 12 13 import com.okhttp.cookie.SimpleCookieJar; 14 import com.okhttp.listener.DisposeDataHandle; 15 import com.okhttp.response.CommonFileCallback; 16 import com.okhttp.response.CommonJsonCallback; 17 import com.okhttp.ssl.HttpsUtils; 18 19 /** 20 * @author vision 21 * @function 用來發送get,post請求的工具類,包括設置一些請求的共用參數,超時、https的認證等等; 22 */ 23 public class CommonOkHttpClient 24 { 25 private static final int TIME_OUT = 30; 26 private static OkHttpClient mOkHttpClient; 27 // private static CommonOkHttpClient mClient = null; 28 29 static 30 { 31 32 OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); 33 //完成對https的認證; 34 okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() 35 { 36 @Override 37 public boolean verify(String hostname, SSLSession session) 38 { 39 return true; 40 } 41 }); 42 43 okHttpClientBuilder.cookieJar(new SimpleCookieJar()); 44 okHttpClientBuilder.connectTimeout(TIME_OUT, TimeUnit.SECONDS); 45 okHttpClientBuilder.readTimeout(TIME_OUT, TimeUnit.SECONDS); 46 okHttpClientBuilder.writeTimeout(TIME_OUT, TimeUnit.SECONDS); 47 okHttpClientBuilder.followRedirects(true);//容許被重定向; 48 /** 49 * trust all the https point 50 */ 51 okHttpClientBuilder.sslSocketFactory(HttpsUtils.getSslSocketFactory()); 52 mOkHttpClient = okHttpClientBuilder.build(); 53 } 54 55 /** 56 * 指定cilent信任指定證書 57 * 58 * @param certificates 59 */ 60 public static void setCertificates(InputStream... certificates) 61 { 62 mOkHttpClient.newBuilder().sslSocketFactory(HttpsUtils.getSslSocketFactory(certificates, null, null)).build(); 63 } 64 65 /** 66 * 指定client信任全部證書 67 */ 68 public static void setCertificates() 69 { 70 mOkHttpClient.newBuilder().sslSocketFactory(HttpsUtils.getSslSocketFactory()); 71 } 72 73 /** 74 * 經過構造好的Request,Callback去發送請求 75 * 76 * @param request 77 * @param callback 78 */ 79 /*get請求*/ 80 public static Call get(Request request, DisposeDataHandle handle) 81 { 82 Call call = mOkHttpClient.newCall(request); 83 call.enqueue(new CommonJsonCallback(handle)); 84 return call; 85 } 86 /*post請求*/ 87 public static Call post(Request request, DisposeDataHandle handle) 88 { 89 Call call = mOkHttpClient.newCall(request); 90 call.enqueue(new CommonJsonCallback(handle)); 91 return call; 92 } 93 /*文件下載*/ 94 public static Call downloadFile(Request request, DisposeDataHandle handle) 95 { 96 Call call = mOkHttpClient.newCall(request); 97 call.enqueue(new CommonFileCallback(handle)); 98 return call; 99 } 100 }
【get請求的調用】
【post請求的調用】
【下載文件的請求】
【上傳文件的響應】
【對點擊事件的響應】