【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请求的调用】
【下载文件的请求】
【上传文件的响应】
【对点击事件的响应】