OkHttp幫助類封裝
阿新 • • 發佈:2019-02-05
package com.flong.utils; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.security.KeyStore; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import okhttp3.Call; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; /** * @Description * ========================================================================================== * 參考部落格:http://www.cnblogs.com/whoislcj/p/5526431.html * http://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html * ========================================================================================== * 秒的換算:ms(毫秒)millisecond ,μs(微秒)microsecond ,ns(納秒)nanosecond ,ps(皮秒)picosecond * 秒的換算 http://blog.chinaunix.net/uid-28458801-id-4144886.html * Semaphored的使用: http://www.cnblogs.com/whgw/archive/2011/09/29/2195555.html * ========================================================================================== * maven匯入okhttp與slf4j的jar 瀏覽器開啟maven倉庫輸入okhttp和slf4j即可,如下: * 倉庫官方網:---->>http://mvnrepository.com/ * * <dependency> * <groupId>com.squareup.okhttp3</groupId> * <artifactId>okhttp</artifactId> * <version>3.9.1</version> * </dependency> * ========================================================================================== * @ClassName OkHttpClientUtil * @Date 2017年7月10日 下午5:39:49 * @Author liangjilong * @Copyright (c) All Rights Reserved, 2017. */ @SuppressWarnings("all") public class OkHttpClientUtil { private static Logger logger = LoggerFactory.getLogger(OkHttpClientUtil.class); //private static String JSON = "application/json; charset=utf-8"; private static String MEDIA_TYPE_JSON= "application/x-www-form-urlencoded; charset=utf-8"; /**使用volatile雙重校驗鎖**/ private static volatile Semaphore semaphore = null; private static volatile OkHttpClient okHttpClient = null; /**建立單例模式*/ public static Semaphore getSemaphoreInstance(){ //只能0個執行緒同時訪問 synchronized (OkHttpClientUtil.class) { if (semaphore == null) { semaphore = new Semaphore(0); } } return semaphore; } /**建立單例模式*/ public static OkHttpClient getInstance(){ synchronized (OkHttpClientUtil.class) { if (okHttpClient == null) { //這裡是以毫秒為單位,1000 毫秒 = 1秒 okHttpClient = new OkHttpClient().newBuilder() .connectTimeout(5000, TimeUnit.SECONDS)// 設定超時時間 .readTimeout(5000, TimeUnit.SECONDS)// 設定讀取超時時間 .writeTimeout(5000, TimeUnit.SECONDS)// 設定寫入超時時間 .build(); } } return okHttpClient; } public static void main(String[] args) throws Exception{ /**組裝引數*/ Map<String, Object> reqMap = new HashMap<String, Object>(); reqMap.put("id", "1"); //============================測試1============================== //String url = "http://localhost:8080/queryUserInfo?"+concatParams(reqMap).toString(); //String retMsg = createAsycHttpPost(url,null,MEDIA_TYPE_JSON); //============================測試2============================== /*String url = "http://localhost:8080/queryUserInfo"; createAsycHttpGet(url, reqMap, MEDIA_TYPE_JSON, new IOkHttpClientCallBack() { @Override public void onSuccessful(String retBody) { System.out.println(retBody); } }); */ //============================測試3============================== /*String url = "http://localhost:8080/queryUserInfo"; String retMsg = createHttpGet(url, reqMap, MEDIA_TYPE_JSON); System.out.println(retMsg);*/ //============================測試4============================== /*String url = "http://localhost:8080/queryUserInfo"; String retMsg = createAsycHttpPost(url, reqMap, MEDIA_TYPE_JSON); System.out.println(retMsg);*/ //============================測試5============================== /* String url = "http://localhost:8080/queryUserInfo"; String retMsg = createPostByAsynWithForm(url, reqMap); System.out.println(retMsg);*/ //============================測試6============================== /* String url = "http://localhost:8080/queryUserInfo"; String retMsg = createPostByAsynWithForm(url, reqMap); System.out.println(retMsg);*/ //============================測試7============================== String url = "https://www.12306.cn/mormhweb/"; String retMsg = createHttpsPost(url,null,MEDIA_TYPE_JSON); System.out.println(retMsg); } /** * @Description 求在子執行緒發起網路請求 * @Author liangjilong * @Date 2017年7月10日 下午3:53:49 * @param url 請求url地址 * @param params 請求body引數 * @param okHttpClientCall 回撥介面 * @throws IOException 引數 * @return void 返回型別 */ public static void createAsycHttpGet(String url,Map<String,Object> params,String contentType,final IOkHttpClientCallBack okHttpClientCall) { // 建立請求物件 Call call = createCall(url, params); //發起非同步的請求 call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) throws IOException { if (response!=null && response.isSuccessful()) { String string = response.body().string(); okHttpClientCall.onSuccessful(string); } } @Override public void onFailure(Call call, IOException e) { String errorLog = getCurrentClassName()+"#createHttpGet,請求異常,異常資訊為:"+e.getMessage(); logger.error("@see "+errorLog); } }); } /** * @Description 求在子執行緒發起網路請求 * @Author liangjilong * @Date 2017年7月10日 下午3:53:49 * @param url 請求url地址 * @param params 請求body引數 * @param okHttpClientCall 回撥介面 * @throws IOException 引數 * @return void 返回型別 */ public static String createAsycHttpGet(String url,Map<String,Object> params,String contentType) { final StringBuilder buffer = new StringBuilder(""); try { // 建立請求物件 Call call = createCall(url, params); //發起非同步的請求 call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) throws IOException { if (response!=null && response.isSuccessful()) { String string = response.body().string(); buffer.append(string); getSemaphoreInstance().release(); } } @Override public void onFailure(Call call, IOException e) { String errorLog = getCurrentClassName()+"#createHttpGet,請求異常,異常資訊為:"+e.getMessage(); logger.error("@see "+errorLog); } }); getSemaphoreInstance().acquire();//獲取許可 return buffer.toString(); } catch (InterruptedException e) { e.printStackTrace(); } return buffer.toString(); } /** * @Description 求在子執行緒發起網路請求 * @Author liangjilong * @Date 2017年7月10日 下午3:53:49 * @param url 請求url地址 * @param params 請求body引數 * @param okHttpClientCall 回撥介面 * @throws IOException 引數 * @return void 返回型別 */ public static String createHttpGet(String url,Map<String,Object> params,String contentType) { try { // 建立請求物件 Call call = createCall(url, params); Response response = call.execute(); if (response!=null && response.isSuccessful() && ObjectUtil.isNotEmpty(response.body())) { //Collection<String> readLines = IOUtil.readLines(byteStream); //System.out.println(readLines); return convertToString(response.body().byteStream()); } } catch (IOException e) { e.printStackTrace(); } return ""; } /** * @Description convertStreamToString * @Author liangjl * @Date 2018年2月9日 下午3:02:00 * @param is * @return 引數 * @return String 返回型別 * @throws */ public static String convertToString(InputStream is) { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder buffer = new StringBuilder(); String line = null; try { while ((line = reader.readLine()) != null) { buffer.append(line + "\r"); } } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return buffer.toString(); } /** * @Description convertStr * @Author liangjl * @Date 2018年2月9日 下午3:01:49 * @param is * @return * @throws IOException 引數 * @return String 返回型別 * @throws */ public static String convertStr(InputStream is) throws IOException { OutputStream baos = new ByteArrayOutputStream(); int i = -1; while ((i = is.read()) != -1) { baos.write(i); } return baos.toString(); } /** * @Description 建立非同步表單Body引數的post請求處理 * @Author liangjilong * @Date 2017年7月11日 上午9:46:04 * @param url 請求連結 * @param params 請求表單body引數 * @param okHttpClientCall 引數 回撥介面 * @return void 返回型別 */ public static void createPostByAsynWithForm(String url,Map<String,Object> params,final IOkHttpClientCallBack okHttpClientCall) { FormBody.Builder builder = new FormBody.Builder(); for (String key : params.keySet()) { builder.add(key, params.get(key).toString()); } RequestBody formBody = builder.build(); logger.info("@see"+getCurrentClassName()+"請求url"+url+",請求引數:"+formBody); Request request = new Request.Builder().url(url).post(formBody).build(); // 建立請求物件 Call call = getInstance().newCall(request); //發起非同步的請求 call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) throws IOException { if (response!=null && response.isSuccessful()) { String string = response.body().string(); okHttpClientCall.onSuccessful(string); } } @Override public void onFailure(Call call, IOException e) { String errorLog = getCurrentClassName()+"#createPostByAsynWithForm,請求異常,異常資訊為:"+e.getMessage(); //okHttpClientCall.onFailure(errorLog); logger.error("@see "+errorLog); } }); } /** * @Description 建立非同步表單Body引數的post請求處理 * @Author liangjilong * @Date 2017年7月11日 上午9:46:04 * @param url 請求連結 * @param params 請求表單body引數 * @param okHttpClientCall 引數 回撥介面 * @return * @return void 返回型別 */ public static String createPostByAsynWithForm(String url,Map<String,Object> params) { final StringBuilder buffer = new StringBuilder(""); try { FormBody.Builder builder = new FormBody.Builder(); for (String key : params.keySet()) { builder.add(key, params.get(key).toString()); } RequestBody formBody = builder.build(); logger.info("@see"+getCurrentClassName()+"請求url"+url+",請求引數:"+formBody); Request request = new Request.Builder().url(url).post(formBody).build(); // 建立請求物件 Call call = getInstance().newCall(request); //發起非同步的請求 call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) throws IOException { if (response!=null && response.isSuccessful()) { String string = response.body().string(); buffer.append(string); getSemaphoreInstance().release(); } } @Override public void onFailure(Call call, IOException e) { String errorLog = getCurrentClassName()+"#createPostByAsynWithForm,請求異常,異常資訊為:"+e.getMessage(); logger.error("@see "+errorLog); } }); getSemaphoreInstance().acquire(); return buffer.toString(); } catch (InterruptedException e) { e.printStackTrace(); } return buffer.toString(); } /** * okHttp createCall * @param url 介面地址 * @param params 請求引數 */ private static Call createCall(String url, Map<String, Object> params) { //補全請求地址,【%s?%s或者%s/%s的使用】第一個%s代表第一個引數,第二個?代表是請求地址的?後面%s代表是組裝戳引數,如: //http://localhost:8080/api/test.do?userId=1212&deviceInfo=PC String requestUrl = String.format("%s?%s", url, concatParams(params).toString()); //建立一個請求 Request request = new Request.Builder().url(requestUrl).build(); return getInstance().newCall(request); } /** * @Description createHttpPost * @Author liangjilong * @Date 2017年7月11日 下午12:20:04 * @param url * @param reqMap * @param contentType * @return 引數 * @return String 返回型別 */ public static String createHttpPost(String url,Map<String,Object> reqMap,String contentType) { try { RequestBody body = createRequestBody(contentType, reqMap); //logger.info("@see"+getCurrentClassName()+"#createHttpPost,請求url"+url+",請求引數:"+body.toString()); final Request request = new Request.Builder().url(url).post(body).build(); // 建立請求物件 final Call call = getInstance().newCall(request); Response response = call.execute(); if (response!=null && response.isSuccessful()) { return convertStr(response.body().byteStream()); } } catch (IOException e) { e.printStackTrace(); } return ""; } /** * @Description 在子執行緒發起 post 請求 * @Author liangjilong * @Date 2017年7月10日 下午3:58:39 * @param url 引數 * @return void 返回型別 */ public static String createAsycHttpPost(String url,Map<String,Object> reqMap,String contentType) { final StringBuilder buffer = new StringBuilder(""); try { final RequestBody body = createRequestBody(contentType, reqMap); //logger.info("@see"+getCurrentClassName()+"#createHttpPost,請求url"+url+",請求引數:"+body.toString()); final Request request = new Request.Builder().url(url).post(body).build(); // 建立請求物件 final Call call = getInstance().newCall(request); // 發起請求 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { String errorLog = getCurrentClassName()+"#createHttpPost,請求異常,異常資訊為:"+e.getMessage(); logger.error("@see "+errorLog); } @Override public void onResponse(Call call, Response response) throws IOException { if (response!=null && response.isSuccessful()) { if(ObjectUtil.isNotEmpty(response.body())){ String string = response.body().string(); buffer.append(string); getSemaphoreInstance().release();//釋放 } } } }); getSemaphoreInstance().acquire();//接受 return buffer.toString(); } catch (Exception e) { e.printStackTrace(); } return buffer.toString(); } /** * @Description 在子執行緒發起 post 請求 * @Author liangjilong * @Date 2017年7月10日 下午3:58:39 * @param url 引數 * @return void 返回型別 */ public static void createAsycHttpPost(String url,Map<String,Object> reqMap,String contentType,final IOkHttpClientCallBack okHttpClientCall) { final RequestBody body = createRequestBody(contentType, reqMap); //logger.info("@see"+getCurrentClassName()+"#createHttpPost,請求url"+url+",請求引數:"+body.toString()); final Request request = new Request.Builder().url(url).post(body).build(); // 建立請求物件 final Call call = getInstance().newCall(request); // 發起請求 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { String errorLog = getCurrentClassName()+"#createHttpPost,請求異常,異常資訊為:"+e.getMessage(); logger.error("@see "+errorLog); } @Override public void onResponse(Call call, Response response) throws IOException { if (response!=null && response.isSuccessful()) { if(ObjectUtil.isNotEmpty(response.body())){ String retBody = response.body().string(); okHttpClientCall.onSuccessful(retBody); } } } }); } /** * * @Description 組裝引數 * @Author liangjilong * @Date 2017年7月10日 下午5:48:13 * @param contentType 請求頭header屬性 * @param params 請求引數 * @return 引數 * @return RequestBody 返回型別 */ private static RequestBody createRequestBody(String contentType,Map<String,Object> params){ MediaType type = MediaType.parse(contentType); String paramStrs = concatParams(params).toString(); return RequestBody.create(type, paramStrs); } /** * @Description 拼接引數 * @Author liangjilong * @Date 2017年7月11日 上午9:34:00 * @param params * @return 引數 * @return StringBuilder 返回型別 */ private static StringBuilder concatParams(Map<String, Object> params) { StringBuilder builder = new StringBuilder("");//請求引數為空給一個預設值空字串 //判斷是空 if (ObjectUtil.isNotEmpty(params)) { int i = 0; for (String key : params.keySet()) { Object value = params.get(key); builder.append(i != 0 ? "&" : ""); builder.append(key + "=" + value); i++; } } return builder; } /** * @Description 建立支援https請求 * @Author liangjl * @Date 2018年2月9日 下午3:25:47 * @param url * @param reqMap * @param contentType 引數 * @return void 返回型別 * @throws */ public static String createHttpsPost(String url,Map<String,Object> reqMap,String contentType) { final StringBuilder buffer = new StringBuilder(""); /**忽略SSL協議證書*/ OkHttpClient build = new OkHttpClient.Builder().sslSocketFactory(createSSLSocketFactory()).hostnameVerifier(new TrustAllHostnameVerifier()).build(); final RequestBody body = createRequestBody(contentType, reqMap); final Request request = new Request.Builder().url(url).post(body).build(); final Call call = build.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { String res = response.body().string(); buffer.append(res); getSemaphoreInstance().release();//釋放 } }); try { getSemaphoreInstance().acquire(); } catch (InterruptedException e1) { e1.printStackTrace(); } return buffer.toString(); } /** * @Description TrustAllCerts * @ClassName TrustAllCerts * @Date 2018年2月9日 下午3:15:23 * @Author liangjl * @Copyright (c) All Rights Reserved, 2018. */ private static class TrustAllCerts implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } /** * @Description 驗證所有主機 * @ClassName TrustAllHostnameVerifier * @Date 2018年2月9日 下午3:15:34 * @Author liangjl * @Copyright (c) All Rights Reserved, 2018. */ private static class TrustAllHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String hostname, SSLSession session) { return true; } } /** * @Description createSSLSocketFactory * @Author liangjl * @Date 2018年2月9日 下午3:15:47 * @return 引數 * @return SSLSocketFactory 返回型別 * @throws */ private static SSLSocketFactory createSSLSocketFactory() { SSLSocketFactory ssfFactory = null; try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, new TrustManager[] { new TrustAllCerts() }, new SecureRandom()); ssfFactory = sc.getSocketFactory(); } catch (Exception e) { } return ssfFactory; } /** * * @Description 獲取當前類名包含有包名路徑 * @Author liangjilong * @Date 2017年5月24日 上午10:33:49 * @param @return 引數 * @return String 返回型別 * @throws */ public static String getCurrentClassName(){ return OkHttpClientUtil.class.getName(); } /** * @Description 定義一個回撥成功的介面. * @ClassName IOkHttpClientCallBack * @Date 2018年2月9日 下午3:34:18 * @Author liangjl * @Copyright (c) All Rights Reserved, 2018. */ public interface IOkHttpClientCallBack { void onSuccessful(String retBody); } }