1
0

OkHttpUtils.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. package com.kmall.common.utils;
  2. import okhttp3.*;
  3. import org.apache.commons.lang3.StringUtils;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import javax.net.ssl.*;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.security.KeyStore;
  10. import java.security.SecureRandom;
  11. import java.security.cert.CertificateException;
  12. import java.security.cert.CertificateFactory;
  13. import java.security.cert.X509Certificate;
  14. import java.util.Arrays;
  15. import java.util.HashMap;
  16. import java.util.Iterator;
  17. import java.util.Map;
  18. import java.util.concurrent.TimeUnit;
  19. /**
  20. * @author Scott Chen
  21. * @date 2017/3/13
  22. */
  23. public class OkHttpUtils {
  24. private static final Logger logger = LoggerFactory.getLogger(OkHttpUtils.class);
  25. public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json;charset=UTF-8");
  26. public static final MediaType MEDIA_TYPE_XML = MediaType.parse("application/xml;charset=UTF-8");
  27. public static final MediaType MEDIA_TYPE_TEXT_HTML = MediaType.parse("text/html;charset=UTF-8");
  28. private static final MediaType MEDIA_TYPE_FORM= MediaType.parse("application/x-www-form-urlencoded");
  29. private static final String SSL = "SSL";
  30. public static final int CONNECT_TIME_OUT = 20;
  31. public static final int READ_TIME = 30;
  32. public static final int WRITE_TIME = 30;
  33. private static final ThreadLocal<OkHttpClient> okHttpClientThreadLocal = new ThreadLocal<>();
  34. private static final ThreadLocal<OkHttpClient> okHttpClientSslThreadLocal = new ThreadLocal<>();
  35. /**
  36. * 禁止调用无参构造
  37. */
  38. private OkHttpUtils() {}
  39. /**
  40. * 默认http
  41. * @return
  42. */
  43. private static OkHttpClient okHttpClient(){
  44. return okHttpClient(null);
  45. }
  46. /**
  47. * https 和 http
  48. * @param ssl 如果需要SSL认证https, ssl值为SSL, 如果ssl为空, 则为http
  49. * @return
  50. */
  51. private static OkHttpClient okHttpClient(String ssl){
  52. return StringUtils.isNotBlank(ssl) && SSL.equals(ssl) ? okHttpInstanceSsl() : okHttpInstance();
  53. }
  54. /**
  55. * https 和 http
  56. * 如果要信息所有证书,
  57. * <code>ssl</code>必须为SSL,
  58. * <code>ignoreHostnameVerifier</code>为true,
  59. * <code>InputStream... certificates</code>为null
  60. *
  61. * @param ssl
  62. * @param ignoreHostnameVerifier 是否忽略Hostname验证
  63. * @param certificates 证书流
  64. * @return
  65. */
  66. private static OkHttpClient okHttpClient(String ssl, boolean ignoreHostnameVerifier, InputStream... certificates){
  67. return StringUtils.isNotBlank(ssl) && SSL.equalsIgnoreCase(ssl)
  68. ? okHttpInstanceSsl(ignoreHostnameVerifier, certificates)
  69. : okHttpInstance();
  70. }
  71. /**
  72. * OkHttpClient 实例
  73. * @return
  74. */
  75. private static OkHttpClient okHttpInstance() {
  76. OkHttpClient client = okHttpClientThreadLocal.get();
  77. if (client == null) {
  78. OkHttpClient.Builder builder = new OkHttpClient.Builder();
  79. builder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
  80. .readTimeout(READ_TIME, TimeUnit.SECONDS)
  81. .writeTimeout(WRITE_TIME, TimeUnit.SECONDS)
  82. .retryOnConnectionFailure(true);
  83. client = builder.build();
  84. okHttpClientThreadLocal.set(client);
  85. }
  86. return client;
  87. }
  88. /**
  89. * OkHttpClient ssl 实例
  90. * 忽略Hostname验证, 并信息所有证书
  91. * @return
  92. */
  93. private static OkHttpClient okHttpInstanceSsl() {
  94. return okHttpInstanceSsl(true, null);
  95. }
  96. /**
  97. * OkHttpClient ssl 实例
  98. * 如果要信息所有证书, <code>InputStream... certificates</code>为null
  99. * @param ignoreHostnameVerifier 是否忽略Hostname验证
  100. * @param certificates 证书流
  101. * @return
  102. */
  103. private static OkHttpClient okHttpInstanceSsl(boolean ignoreHostnameVerifier, InputStream... certificates) {
  104. OkHttpClient client = okHttpClientSslThreadLocal.get();
  105. if (client == null) {
  106. X509TrustManager[] trustManager = buildX509TrustManager(certificates);
  107. SSLSocketFactory sslSocketFactory = buildSSLSocketFactory(trustManager);
  108. OkHttpClient.Builder builder = new OkHttpClient.Builder();
  109. builder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
  110. .readTimeout(READ_TIME, TimeUnit.SECONDS)
  111. .writeTimeout(WRITE_TIME, TimeUnit.SECONDS);
  112. //是否忽略host验证
  113. if (ignoreHostnameVerifier) {
  114. builder.hostnameVerifier(getHostnameVerifier());
  115. }
  116. builder.sslSocketFactory(sslSocketFactory, trustManager[0])
  117. .retryOnConnectionFailure(true);
  118. client = builder.build();
  119. okHttpClientSslThreadLocal.set(client);
  120. }
  121. return client;
  122. }
  123. //------------------------------ build RequestBody ------------------------------
  124. public static RequestBody buildRequestBody(MediaType mediaType, String json) {
  125. return RequestBody.create(mediaType, json);
  126. }
  127. public static RequestBody buildRequestBody(String key, Object value) {
  128. if (StringUtils.isBlank(key)) {
  129. return null;
  130. }
  131. Map<String, Object> param = new HashMap<>();
  132. param.put(key, value);
  133. return buildRequestBody(param);
  134. }
  135. public static RequestBody buildMapStringRequestBody(Map<String, String> params) {
  136. FormBody.Builder builder = new FormBody.Builder();
  137. Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
  138. while (iterator.hasNext()) {
  139. Map.Entry<String, String> entry = iterator.next();
  140. builder.add(entry.getKey(), entry.getValue());
  141. }
  142. return builder.build();
  143. }
  144. /**
  145. * 构造RequestBody
  146. *
  147. * @param params
  148. * @return
  149. */
  150. public static RequestBody buildRequestBody(Map<String, Object> params) {
  151. FormBody.Builder builder = new FormBody.Builder();
  152. Iterator<Map.Entry<String, Object>> iterator = params.entrySet().iterator();
  153. while (iterator.hasNext()) {
  154. Map.Entry<String, Object> entry = iterator.next();
  155. builder.add(entry.getKey(), JacksonUtils.toJson(entry.getValue()));
  156. }
  157. return builder.build();
  158. }
  159. //------------------------------ build Request ------------------------------
  160. /**
  161. * 以字符串数据构建
  162. * @param json
  163. * @param url
  164. * @param type
  165. * @return
  166. */
  167. public static Request buildRequest(String json, String url, String type) {
  168. //默认JSON
  169. MediaType mediaType = MEDIA_TYPE_JSON;
  170. if (type.equalsIgnoreCase("text_html")) {
  171. mediaType = MEDIA_TYPE_TEXT_HTML;
  172. }else if (type.equalsIgnoreCase("form")) {
  173. mediaType = MEDIA_TYPE_FORM;
  174. }else if (type.equalsIgnoreCase("xml")) {
  175. mediaType = MEDIA_TYPE_XML;
  176. }
  177. RequestBody body = buildRequestBody(mediaType, json);
  178. return buildRequest(body, url);
  179. }
  180. public static Request buildStringRequest(Map<String, String> param, String url) {
  181. return buildRequest(buildMapStringRequestBody(param), url);
  182. }
  183. /**
  184. * 构建Request
  185. * @param param
  186. * @param url
  187. * @return
  188. */
  189. public static Request buildRequest(Map<String, Object> param, String url) {
  190. return buildRequest(buildRequestBody(param), url);
  191. }
  192. /**
  193. * 构建Request
  194. * @param key
  195. * @param value
  196. * @param url
  197. * @return
  198. */
  199. public static Request buildRequest(String key, Object value, String url) {
  200. return buildRequest(buildRequestBody(key, value), url);
  201. }
  202. /**
  203. * 构建Request
  204. * @param body
  205. * @param url
  206. * @return
  207. */
  208. public static Request buildRequest(RequestBody body, String url) {
  209. return new Request.Builder()
  210. .url(url)
  211. .post(body)
  212. .build();
  213. }
  214. //------------------------------ post ------------------------------
  215. public static String post(String json, String url, String type, String ssl) {
  216. return post(buildRequest(json, url, type), ssl);
  217. }
  218. public static String post(String key, Object value, String url, String ssl) {
  219. return post(buildRequest(key, value, url), ssl);
  220. }
  221. public static String postString(Map<String, String> param, String url, String ssl) {
  222. return post(buildStringRequest(param, url), ssl);
  223. }
  224. public static String post(Map<String, Object> param, String url, String ssl) {
  225. return post(buildRequest(param, url), ssl);
  226. }
  227. /**
  228. * 同步访问,返回结果字符串
  229. * 可能超时
  230. *
  231. * @param request
  232. * @param ssl
  233. * @return
  234. * @throws IOException
  235. */
  236. public static String post(Request request, String ssl) {
  237. String result = "";
  238. try {
  239. Response response = okHttpClient(ssl).newCall(request).execute();
  240. if (response.isSuccessful()) {
  241. result = response.body().string();
  242. } else {
  243. logger.error("okhttp3 post failed.");
  244. }
  245. } catch (IOException e) {
  246. logger.error("okhttp3 post throw IOException, {}", e.getMessage());
  247. }
  248. return result;
  249. }
  250. /**
  251. * 同步访问,返回Response
  252. * 可能超时
  253. *
  254. * @param request
  255. * @param ssl
  256. * @return
  257. * @throws IOException
  258. */
  259. public static String postReturnResponse(Request request, String ssl) {
  260. try {
  261. return okHttpClient(ssl).newCall(request).execute().body().string();
  262. } catch (IOException e) {
  263. logger.error("okhttp3 post throw IOException, {}", e.getMessage());
  264. }
  265. return null;
  266. }
  267. /**
  268. * 异步访问,回调结果
  269. * @param request
  270. * @param ssl
  271. * @param responseCallback
  272. */
  273. public static void asyncPostCallback(Request request, String ssl, Callback responseCallback) {
  274. okHttpClient(ssl).newCall(request).enqueue(responseCallback);
  275. }
  276. /**
  277. * 异步访问,无结果返回
  278. * @param request
  279. * @param ssl
  280. */
  281. public static void asyncPost(Request request, String ssl) {
  282. okHttpClient(ssl).newCall(request).enqueue(new Callback() {
  283. @Override
  284. public void onFailure(Call call, IOException e) {
  285. }
  286. @Override
  287. public void onResponse(Call call, Response response) throws IOException {
  288. }
  289. });
  290. }
  291. //------------------------------ ssl ------------------------------
  292. /**
  293. * 获取主机验证 HostnameVerifier
  294. * @return
  295. */
  296. public static HostnameVerifier getHostnameVerifier() {
  297. return new HostnameVerifier() {
  298. @Override
  299. public boolean verify(String s, SSLSession sslSession) {
  300. return true;
  301. }
  302. };
  303. }
  304. /**
  305. * 自定义证书
  306. *
  307. * @param certificates
  308. * @return
  309. */
  310. private static KeyStore generateKeyStore(InputStream... certificates) {
  311. try {
  312. CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
  313. KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
  314. keyStore.load(null);
  315. int index = 0;
  316. if (certificates !=null && certificates.length > 0) {
  317. for (InputStream certificate : certificates) {
  318. String certificateAlias = Integer.toString(index++);
  319. keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
  320. try {
  321. if (certificate != null) {
  322. certificate.close();
  323. }
  324. } catch (IOException e) {
  325. }
  326. }
  327. }
  328. return keyStore;
  329. } catch (Exception e) {
  330. e.printStackTrace();
  331. }
  332. return null;
  333. }
  334. /**
  335. * 证书管理
  336. * 信任所有证书
  337. * @return
  338. */
  339. private static X509TrustManager[] buildX509TrustManager(){
  340. return buildX509TrustManager(null);
  341. }
  342. /**
  343. * 证书管理
  344. * 如果要信任所有证书,<code>InputStream... certificates</code>为null
  345. * @param certificates 证书文件流
  346. * @return
  347. */
  348. private static X509TrustManager[] buildX509TrustManager(InputStream... certificates) {
  349. try {
  350. if (certificates == null) {
  351. // 信任所有证书
  352. return new X509TrustManager[]{
  353. new X509TrustManager() {
  354. @Override
  355. public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
  356. }
  357. @Override
  358. public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
  359. }
  360. @Override
  361. public X509Certificate[] getAcceptedIssuers() {
  362. return new X509Certificate[]{};
  363. }
  364. }
  365. };
  366. }
  367. // 信任自定义证书
  368. KeyStore keyStore = generateKeyStore(certificates);
  369. TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
  370. TrustManagerFactory.getDefaultAlgorithm());
  371. trustManagerFactory.init(keyStore);
  372. TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
  373. if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
  374. throw new IllegalStateException("Unexpected default trust managers:"
  375. + Arrays.toString(trustManagers));
  376. }
  377. return (X509TrustManager[]) trustManagers;
  378. } catch (Exception e) {
  379. e.printStackTrace();
  380. }
  381. return null;
  382. }
  383. private static SSLSocketFactory buildSSLSocketFactory() {
  384. return buildSSLSocketFactory((InputStream)null);
  385. }
  386. private static SSLSocketFactory buildSSLSocketFactory(InputStream... certificates) {
  387. try {
  388. TrustManager[] trustManager = buildX509TrustManager(certificates);
  389. return buildSSLSocketFactory(trustManager);
  390. } catch (Exception e) {
  391. e.printStackTrace();
  392. }
  393. return null;
  394. }
  395. private static SSLSocketFactory buildSSLSocketFactory(TrustManager[] trustManager) {
  396. try {
  397. if (trustManager == null) {
  398. throw new IllegalStateException("TrustManager is null");
  399. }
  400. SSLContext sslContext = SSLContext.getInstance(SSL);
  401. sslContext.init(null, trustManager, new SecureRandom());
  402. return sslContext.getSocketFactory();
  403. } catch (Exception e) {
  404. e.printStackTrace();
  405. }
  406. return null;
  407. }
  408. }