OkHttpUtils.java 15 KB

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