package com.hujiang.juice.common.utils.rest; import lombok.Data; import lombok.extern.slf4j.Slf4j; import okhttp3.*; import javax.net.ssl.*; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Map; import java.util.concurrent.TimeUnit; /** * Created by xujia on 16/6/8. * <p> * config in startup.properties : * ok.http.time.out=XX(default = 10) * ok.http.retry.times=X(default = 3) * if u don't wanner default value */ @Slf4j @Data public class OkHttpUtils { private static OkHttpUtils instance; private OkHttpClient okHttpClient; private OkHttpClient okHttpsClient; private long connectTimeOut; private long readTimeOut; private long writeTimeOut; private int retrys; private OkHttpClient.Builder getBuilder(long connectTimeOut, long readTimeOut, long writeTimeOut, int retrys) { OkHttpClient.Builder builder = new OkHttpClient.Builder(); return builder.connectTimeout(connectTimeOut, TimeUnit.SECONDS) .readTimeout(readTimeOut, TimeUnit.SECONDS) .writeTimeout(writeTimeOut, TimeUnit.SECONDS) .addInterceptor( new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { // try the request Request request = chain.request(); Response response = chain.proceed(request); int tryCount = 0; while (!response.isSuccessful() && tryCount < retrys) { response.close(); response = chain.proceed(request); tryCount++; } return response; } } ); } private OkHttpUtils(long connectTimeOut, long readTimeOut, long writeTimeOut, int retrys) { OkHttpClient.Builder builder = getBuilder(connectTimeOut, readTimeOut, writeTimeOut, retrys); this.connectTimeOut = connectTimeOut; this.readTimeOut = readTimeOut; this.writeTimeOut = writeTimeOut; this.retrys = retrys; okHttpClient = builder.build(); try { ssl(builder); okHttpsClient = builder.build(); } catch (NoSuchAlgorithmException | KeyManagementException e) { log.error(e.getMessage(), e); throw new RuntimeException(e.getMessage()); } } public static OkHttpUtils getInstance(long connectTimeOut, long readTimeOut, long writeTimeOut, int retrys) { if(null == instance) { synchronized (OkHttpUtils.class) { if(null == instance) { instance = new OkHttpUtils(connectTimeOut, readTimeOut, writeTimeOut, retrys); } } } return instance; } private boolean checkSSL(String urlStr) throws MalformedURLException { URL url = new URL(urlStr); return "https".equalsIgnoreCase(url.getProtocol()); } private void ssl(OkHttpClient.Builder builder) throws NoSuchAlgorithmException, KeyManagementException { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, new TrustManager[]{ trustManager }, new SecureRandom()); builder.sslSocketFactory(sc.getSocketFactory(), trustManager).hostnameVerifier(hostnameVerifier); } private static final X509TrustManager trustManager = 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[0]; } }; private static final HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { return true; } }; public Response put(String url, RequestBody requestBody, Map<String, String> headerMaps) throws IOException { return doRequest("PUT", url, requestBody, headerMaps); } public Response post(String url, RequestBody requestBody, Map<String, String> headerMaps) throws IOException { return doRequest("POST", url, requestBody, headerMaps); } public Response delete(String url, RequestBody requestBody, Map<String, String> headerMaps) throws IOException { return doRequest("DELETE", url, requestBody, headerMaps); } public Response get(String url, Map<String, String> headerMaps) throws IOException { return doRequest("GET", url, null, headerMaps); } public Response doRequest(String type, String url, RequestBody body, Map<String, String> headerMaps) throws IOException { return doOkRequest(type, url, body, headerMaps); } private OkHttpClient getClient(String url) throws MalformedURLException { if(checkSSL(url)) { return okHttpsClient; } return okHttpClient; } /** * @param type request type: get, put, post or delete * @param url * @param body * @param headerMaps * @return * @throws IOException */ public Response doOkRequest(String type, String url, RequestBody body, Map<String, String> headerMaps) throws IOException { Response response = null; try { Request.Builder builder = new Request.Builder().url(url); if (null != headerMaps && headerMaps.size() > 0) builder.headers(Headers.of(headerMaps)); switch (type) { case "PUT": case "POST": case "DELETE": case "PATCH": if(null == body) { body = RequestBody.create(null, new byte[0]); } builder.method(type, body); break; case "GET": case "HEAD": builder.method(type, null); break; } Request request = builder.build(); OkHttpClient client = getClient(url); response = client.newCall(request).execute(); if (!response.isSuccessful()) { int code = response.code(); StringBuilder message = new StringBuilder(); message.append(response.message()); response.close(); log.warn("Unexpected code :" + code + ", cause : " + message.toString()); throw new IOException(message.toString()); } return response; } catch (IOException e) { if (null != response) { response.close(); } throw e; } } }