123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- package com.emato.common.utils.oms;
- import okhttp3.*;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.net.ssl.*;
- import java.io.IOException;
- import java.io.InputStream;
- 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.Arrays;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.concurrent.TimeUnit;
- /**
- * @author Scott Chen
- * @date 2017/3/13
- */
- public class OkHttpUtils {
- private static final Logger logger = LoggerFactory.getLogger(OkHttpUtils.class);
- public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json;charset=UTF-8");
- public static final MediaType MEDIA_TYPE_XML = MediaType.parse("application/xml;charset=UTF-8");
- public static final MediaType MEDIA_TYPE_TEXT_HTML = MediaType.parse("text/html;charset=UTF-8");
- private static final MediaType MEDIA_TYPE_FORM= MediaType.parse("application/x-www-form-urlencoded");
- private static final String SSL = "SSL";
- public static final int CONNECT_TIME_OUT = 20;
- public static final int READ_TIME = 30;
- public static final int WRITE_TIME = 30;
- private static final ThreadLocal<OkHttpClient> okHttpClientThreadLocal = new ThreadLocal<>();
- private static final ThreadLocal<OkHttpClient> okHttpClientSslThreadLocal = new ThreadLocal<>();
- /**
- * 禁止调用无参构造
- */
- private OkHttpUtils() {}
- /**
- * 默认http
- * @return
- */
- private static OkHttpClient okHttpClient(){
- return okHttpClient(null);
- }
- /**
- * https 和 http
- * @param ssl 如果需要SSL认证https, ssl值为SSL, 如果ssl为空, 则为http
- * @return
- */
- private static OkHttpClient okHttpClient(String ssl){
- return StringUtils.isNotBlank(ssl) && SSL.equals(ssl) ? okHttpInstanceSsl() : okHttpInstance();
- }
- /**
- * https 和 http
- * 如果要信息所有证书,
- * <code>ssl</code>必须为SSL,
- * <code>ignoreHostnameVerifier</code>为true,
- * <code>InputStream... certificates</code>为null
- *
- * @param ssl
- * @param ignoreHostnameVerifier 是否忽略Hostname验证
- * @param certificates 证书流
- * @return
- */
- private static OkHttpClient okHttpClient(String ssl, boolean ignoreHostnameVerifier, InputStream... certificates){
- return StringUtils.isNotBlank(ssl) && SSL.equals(ssl)
- ? okHttpInstanceSsl(ignoreHostnameVerifier, certificates)
- : okHttpInstance();
- }
- /**
- * OkHttpClient 实例
- * @return
- */
- private static OkHttpClient okHttpInstance() {
- OkHttpClient client = okHttpClientThreadLocal.get();
- if (client == null) {
- synchronized (OkHttpUtils.class) {
- OkHttpClient.Builder builder = new OkHttpClient.Builder();
- builder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
- .readTimeout(READ_TIME, TimeUnit.SECONDS)
- .writeTimeout(WRITE_TIME, TimeUnit.SECONDS)
- .retryOnConnectionFailure(true);
- client = builder.build();
- okHttpClientThreadLocal.set(client);
- }
- }
- return client;
- }
- /**
- * OkHttpClient ssl 实例
- * 忽略Hostname验证, 并信息所有证书
- * @return
- */
- private static OkHttpClient okHttpInstanceSsl() {
- return okHttpInstanceSsl(true, new InputStream[]{});
- }
- /**
- * OkHttpClient ssl 实例
- * 如果要信息所有证书, <code>InputStream... certificates</code>为null
- * @param ignoreHostnameVerifier 是否忽略Hostname验证
- * @param certificates 证书流
- * @return
- */
- private static OkHttpClient okHttpInstanceSsl(boolean ignoreHostnameVerifier, InputStream... certificates) {
- OkHttpClient client = okHttpClientSslThreadLocal.get();
- if (client == null) {
- synchronized (OkHttpUtils.class) {
- X509TrustManager[] trustManager = buildX509TrustManager(certificates);
- SSLSocketFactory sslSocketFactory = buildSSLSocketFactory(trustManager);
- OkHttpClient.Builder builder = new OkHttpClient.Builder();
- builder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
- .readTimeout(READ_TIME, TimeUnit.SECONDS)
- .writeTimeout(WRITE_TIME, TimeUnit.SECONDS)
- .retryOnConnectionFailure(true);
- //是否忽略host验证
- if (ignoreHostnameVerifier) {
- builder.hostnameVerifier(getHostnameVerifier());
- }
- builder.sslSocketFactory(sslSocketFactory, trustManager[0])
- .retryOnConnectionFailure(true);
- client = builder.build();
- okHttpClientSslThreadLocal.set(client);
- }
- }
- return client;
- }
- //------------------------------ build RequestBody ------------------------------
- public static RequestBody buildRequestBody(MediaType mediaType, String json) {
- return RequestBody.create(mediaType,json );
- }
- public static RequestBody buildRequestBody(String key, Object value) {
- if (org.apache.commons.lang3.StringUtils.isBlank(key)) {
- return null;
- }
- Map<String, Object> param = new HashMap<>();
- param.put(key, value);
- return buildRequestBody(param);
- }
- public static RequestBody buildMapStringRequestBody(Map<String, String> params) {
- FormBody.Builder builder = new FormBody.Builder();
- Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
- while (iterator.hasNext()) {
- Map.Entry<String, String> entry = iterator.next();
- builder.add(entry.getKey(), entry.getValue());
- }
- return builder.build();
- }
- /**
- * 构造RequestBody
- *
- * @param params
- * @return
- */
- public static RequestBody buildRequestBody(Map<String, Object> params) {
- FormBody.Builder builder = new FormBody.Builder();
- Iterator<Map.Entry<String, Object>> iterator = params.entrySet().iterator();
- while (iterator.hasNext()) {
- Map.Entry<String, Object> entry = iterator.next();
- builder.add(entry.getKey(), JacksonUtils.toJsonStr(entry.getValue()));
- }
- return builder.build();
- }
- //------------------------------ build Request ------------------------------
- /**
- * 以字符串数据构建
- * @param json
- * @param url
- * @param type
- * @return
- */
- public static Request buildRequest(String json, String url, String type) {
- //默认JSON
- MediaType mediaType = MEDIA_TYPE_JSON;
- type = StringUtils.isBlank(type) ? "" : type;
- json = StringUtils.isBlank(json) ? "" : json;
- if (type.equalsIgnoreCase("text_html")) {
- mediaType = MEDIA_TYPE_TEXT_HTML;
- }else if (type.equalsIgnoreCase("form")) {
- mediaType = MEDIA_TYPE_FORM;
- }else if (type.equalsIgnoreCase("xml")) {
- mediaType = MEDIA_TYPE_XML;
- }
- RequestBody body = buildRequestBody(mediaType, json);
- return buildRequest(body, url);
- }
- public static Request buildStringRequest(Map<String, String> param, String url) {
- return buildRequest(buildMapStringRequestBody(param), url);
- }
- /**
- * 构建Request
- * @param param
- * @param url
- * @return
- */
- public static Request buildRequest(Map<String, Object> param, String url) {
- return buildRequest(buildRequestBody(param), url);
- }
- /**
- * 构建Request
- * @param key
- * @param value
- * @param url
- * @return
- */
- public static Request buildRequest(String key, Object value, String url) {
- return buildRequest(buildRequestBody(key, value), url);
- }
- /**
- * 构建Request
- * @param body
- * @param url
- * @return
- */
- public static Request buildRequest(RequestBody body, String url) {
- return new Request.Builder()
- .url(url)
- .post(body)
- .build();
- }
- //------------------------------ post ------------------------------
- public static String post(String json, String url, String type, String ssl) {
- return post(buildRequest(json, url, type), ssl);
- }
- public static String post(String key, Object value, String url, String ssl) {
- return post(buildRequest(key, value, url), ssl);
- }
- public static String postString(Map<String, String> param, String url, String ssl) {
- return post(buildStringRequest(param, url), ssl);
- }
- public static String post(Map<String, Object> param, String url, String ssl) {
- return post(buildRequest(param, url), ssl);
- }
- /**
- * 同步访问,返回结果字符串
- * 可能超时
- *
- * @param request
- * @param ssl
- * @return
- * @throws IOException
- */
- public static String post(Request request, String ssl) {
- String result = "";
- try {
- Response response = okHttpClient(ssl).newCall(request).execute();
- if (response.isSuccessful()) {
- result = response.body().string();
- } else {
- logger.error("okhttp3 post failed.");
- }
- } catch (IOException e) {
- logger.error("okhttp3 post throw IOException, {}", e.getMessage());
- }
- return result;
- }
- /**
- * 同步访问,返回Response
- * 可能超时
- *
- * @param request
- * @param ssl
- * @return
- * @throws IOException
- */
- public static String postReturnResponse(Request request, String ssl) {
- try {
- return okHttpClient(ssl).newCall(request).execute().body().string();
- } catch (IOException e) {
- logger.error("okhttp3 post throw IOException, {}", e.getMessage());
- }
- return null;
- }
- /**
- * 异步访问,回调结果
- * @param request
- * @param ssl
- * @param responseCallback
- */
- public static void asyncPostCallback(Request request, String ssl, Callback responseCallback) {
- okHttpClient(ssl).newCall(request).enqueue(responseCallback);
- }
- /**
- * 异步访问,无结果返回
- * @param request
- * @param ssl
- */
- public static void asyncPost(Request request, String ssl) {
- okHttpClient(ssl).newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- }
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- }
- });
- }
- //------------------------------ ssl ------------------------------
- /**
- * 获取主机验证 HostnameVerifier
- * @return
- */
- public static HostnameVerifier getHostnameVerifier() {
- return new HostnameVerifier() {
- @Override
- public boolean verify(String s, SSLSession sslSession) {
- return true;
- }
- };
- }
- /**
- * 自定义证书
- *
- * @param certificates
- * @return
- */
- private static KeyStore generateKeyStore(InputStream... certificates) {
- try {
- CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
- KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- keyStore.load(null);
- int index = 0;
- if (certificates !=null && certificates.length > 0) {
- for (InputStream certificate : certificates) {
- String certificateAlias = Integer.toString(index++);
- keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
- try {
- if (certificate != null) {
- certificate.close();
- }
- } catch (IOException e) {
- }
- }
- }
- return keyStore;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * 证书管理
- * 信任所有证书
- * @return
- */
- private static X509TrustManager[] buildX509TrustManager(){
- return buildX509TrustManager(new InputStream[]{});
- }
- /**
- * 证书管理
- * 如果要信任所有证书,<code>InputStream... certificates</code>为null
- * @param certificates 证书文件流
- * @return
- */
- private static X509TrustManager[] buildX509TrustManager(InputStream... certificates) {
- try {
- if (certificates == null) {
- // 信任所有证书
- return new X509TrustManager[]{
- new X509TrustManager() {
- @Override
- public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
- }
- @Override
- public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
- }
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return new X509Certificate[]{};
- }
- }
- };
- }
- // 信任自定义证书
- KeyStore keyStore = generateKeyStore(certificates);
- TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
- TrustManagerFactory.getDefaultAlgorithm());
- trustManagerFactory.init(keyStore);
- TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
- if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
- throw new IllegalStateException("Unexpected default trust managers:"
- + Arrays.toString(trustManagers));
- }
- return (X509TrustManager[]) trustManagers;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- private static SSLSocketFactory buildSSLSocketFactory() {
- return buildSSLSocketFactory((InputStream)null);
- }
- private static SSLSocketFactory buildSSLSocketFactory(InputStream... certificates) {
- try {
- TrustManager[] trustManager = buildX509TrustManager(certificates);
- return buildSSLSocketFactory(trustManager);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- private static SSLSocketFactory buildSSLSocketFactory(TrustManager[] trustManager) {
- try {
- if (trustManager == null) {
- throw new IllegalStateException("TrustManager is null");
- }
- SSLContext sslContext = SSLContext.getInstance(SSL);
- sslContext.init(null, trustManager, new SecureRandom());
- return sslContext.getSocketFactory();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- }
|