zoukankan      html  css  js  c++  java
  • OKHttp使用demo(证书过滤,证书导入,代理访问,文件上传)

    此demo需要引入okhttp-3.4.1.jar 和 okio-1.9.0.jar(这两个包需要jdk1.7以上的环境)

    对应pom文件是:

    		<dependency>
    			<groupId>com.squareup.okhttp3</groupId>
    			<artifactId>okhttp</artifactId>
    			<version>3.4.1</version>
    		</dependency>
    

     demo文件:HttpClientManage.java 其中的一些日志打印需要替换下

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.InetSocketAddress;
    import java.net.Proxy;
    import java.net.URLEncoder;
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.cert.CertificateException;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.util.Arrays;
    import java.util.Map;
    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 okhttp3.Callback;
    import okhttp3.FormBody;
    import okhttp3.MediaType;
    import okhttp3.MultipartBody;
    import okhttp3.RequestBody;
    import okhttp3.FormBody.Builder;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    
    import org.apache.commons.lang.StringUtils;
    
    import test2.LogUtil;
    
    /**
     * OkHttp官方文档并不建议我们创建多个OkHttpClient,因此全局使用一个。 
     * 支持自动读取配置文件中的过期时间配置以及CA导入,或采用默认配置
     * 支持实现同步请求(普通+快速),异步请求(普通+快速)
     * 支持头文件设置
     * 支持https
     * 支持代理ip port 若未设置代理ip等信息则采用本机ip常规方式进行请求
     * @date 2017年6月10日 下午5:07:14
     */
    public class HttpClientManage
    {
        private static volatile HttpClientManage instance;
    
        private static int CONNECT_TIMEOUT = 60;
        private static int READ_TIMEOUT = 100;
        private static int WRITE_TIMEOUT = 60;
        private static int CONNECT_TIMEOUT_QUICK = 3;
        private static int READ_TIMEOUT_QUICK = 5;
        private static int WRITE_TIMEOUT_QUICK = 3;
        /**
         * ca证书存放路径
         */
        private static String CA_PATH = null;
        /**
         * 代理域名或者IP
         */
        private static String PROXY_IP = null;
        /**
         * 代理端口
         */
        private static int PROXY_PORT = 80;
        /**
         * 是否忽略正式
         */
        private static boolean IS_INORE_CA = true;
    
        private static String PARAM_SPLIT_FIRST = "?";
        private static String PARAM_SPLIT_VAL = "=";
        private static String PARAM_SPLIT = "&";
        private static String DEFAULT_ENCODE = "UTF-8";
        /**
         * ca证书别名
         */
        private static String SSL_KEY_ALIAS = "DIY";
    
        /**
         * 证书工厂
         */
        private static SSLSocketFactory sslSocketFactory = null;
        /**
         * 证书类型
         */
        private static X509TrustManager trustManager = null;
    
        /**
         * 正常请求
         */
        private static OkHttpClient mOkHttpClient;
    
        /**
         * 局域网内调用的快速请求 响应时间要求比普通正常请求快20倍
         */
        private static OkHttpClient mOkHttpClientQuick;
    
        /**
         * 代理请求
         */
        private static OkHttpClient mOkHttpClientProxy;
    
        /**
         * 单体实例类
         * @return
         * @exception/throws [异常类型] [异常说明](可选)
         * @date 2017年6月10日 下午5:00:57
         * @since 1.0.0
         */
        public static HttpClientManage getInstance()
        {
            if (instance == null)
            {
                synchronized (HttpClientManage.class)
                {
                    if (instance == null)
                    {
                        instance = new HttpClientManage();
                    }
                }
            }
            return instance;
        }
        
        /**
         * 简单调用: get(url)
         * 加参数调用: get(url, param)
         * 加参数同时加头文件调用: get(url, param, header)
         * 仅加头文件调用: get(url, null, header)
         * @param url 请求地址
         * @param params 如果有多个map传入, 则默认第一个为参数param, 第二个为header param
         * @return
         * @exception/throws [异常类型] [异常说明](可选)
         * @date 2017年6月10日 下午5:01:50
         * @since 1.0.0
         */
        public String get(String url, Map<String, String>... params)
        {
            return getCommon(url, mOkHttpClient, params);
        }
    
        public String getQuick(String url, Map<String, String>... params)
        {
            return getCommon(url, mOkHttpClientQuick, params);
        }
    
        public String getProxy(String url, Map<String, String>... params)
        {
            if (null != mOkHttpClientProxy)
            {
                return getCommon(url, mOkHttpClientProxy, params);
            }
            return get(url, params);
        }
    
        public String post(String url, Map<String, String>... params)
        {
            return postCommon(url, mOkHttpClient, params);
        }
    
        public String postQuick(String url, Map<String, String>... params)
        {
            return postCommon(url, mOkHttpClientQuick, params);
        }
    
        public String postProxy(String url, Map<String, String>... params)
        {
            if (null != mOkHttpClientProxy)
            {
                return postCommon(url, mOkHttpClientProxy, params);
            }
            return post(url, params);
        }
    
        /**
         * 异步调用
         * 简单调用: get(url, callback)
         * 加参数调用: get(url, callbackparam)
         * 加参数同时加头文件调用: get(url, callback, param, header)
         * 仅加头文件调用: get(url, callback, null, header)
         * @param url 请求地址
         * @param callback 回调函数
         * @param params 如果有多个map传入, 则默认第一个为参数param, 第二个为header param
         * @exception/throws [异常类型] [异常说明](可选)
         * @date 2017年6月10日 下午5:02:59
         * @since 1.0.0
         */
        public void getAsyn(String url, Callback callback, Map<String, String>... params)
        {
            getCommonAsyn(url, callback, mOkHttpClient, params);
        }
    
        public void getQuickAsyn(String url, Callback callback, Map<String, String>... params)
        {
            getCommonAsyn(url, callback, mOkHttpClientQuick, params);
        }
    
        public void getProxyAsyn(String url, Callback callback, Map<String, String>... params)
        {
            if (null != mOkHttpClientProxy)
            {
                getCommonAsyn(url, callback, mOkHttpClientProxy, params);
                return;
            }
            getAsyn(url, callback, params);
        }
    
        public void postAsyn(String url, Callback callback, Map<String, String>... params)
        {
            postCommonAsyn(url, callback, mOkHttpClient, params);
        }
    
        public void postQuickAsyn(String url, Callback callback, Map<String, String>... params)
        {
            postCommonAsyn(url, callback, mOkHttpClientQuick, params);
        }
    
        public void postProxyAsyn(String url, Callback callback, Map<String, String>... params)
        {
            if (null != mOkHttpClientProxy)
            {
                postCommonAsyn(url, callback, mOkHttpClientProxy, params);
                return;
            }
            postAsyn(url, callback, params);
        }
    
        private HttpClientManage()
        {
            init();
        }
    
        private void init()
        {
            // 初始化静态 如果不需要配置文件来进行参数配置,可以将此方法去掉
            initProperty();
            // 初始化CA
            initCa();
            initNormalClient();
            initQuickClient();
            initProxyClient();
        }
    
        /**
         * 初始化参数
         * @exception/throws [异常类型] [异常说明](可选)
         * @date 2017年6月10日 下午5:05:34
         * @since 1.0.0
         */
        private void initProperty()
        {
            //IS_INORE_CA = true;
        }
    
        private void initCa()
        {
            try
            {
                if (IS_INORE_CA)
                {
                    trustManager = new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
                        {
                        }
    
                        @Override
                        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
                        {
                        }
                        @Override
                        public X509Certificate[] getAcceptedIssuers()
                        {
                            X509Certificate[] x509Certificates = new X509Certificate[0];
                            return x509Certificates;
                        }
                    };
                }
                else
                {
                    if (StringUtils.isEmpty(CA_PATH))
                    {
                        return;
                    }
                    // 读取key
                    KeyStore keyStore = readKeyStore();
                    if (null == keyStore)
                    {
                        return;
                    }
                    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));
                    }
                    trustManager = (X509TrustManager) trustManagers[0];
                }
                
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, new TrustManager[] { trustManager }, null);
                sslSocketFactory = sslContext.getSocketFactory();
            }
            catch (Exception e)
            {
                LogUtil.error("initCa error.", e);
            }
        }
    
        private KeyStore readKeyStore()
        {
            File file = new File(CA_PATH);
            if (!file.exists())
            {
                return null;
            }
    
            KeyStore keyStore = null;
            CertificateFactory certificateFactory = null;
            try
            {
                certificateFactory = CertificateFactory.getInstance("X.509");
                keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                keyStore.load(null);
            }
            catch (Exception e1)
            {
                LogUtil.error(null, e1);
            }
    
            if (null == keyStore || null == certificateFactory)
            {
                return null;
            }
    
            InputStream inputStream = null;
            if (!file.isDirectory())
            {
                try
                {
                    inputStream = new FileInputStream(file);
                    addOneCer(certificateFactory, keyStore, SSL_KEY_ALIAS, inputStream);
                }
                catch (Exception e)
                {
                    LogUtil.error(null, e);
                }
                finally
                {
                    try
                    {
                        if (inputStream != null)
                            inputStream.close();
                    }
                    catch (IOException e)
                    {
                        LogUtil.error(null, e);
                    }
                }
            }
            else
            {
                int index = 0;
                String certificateAlias;
                for (File cerFile : file.listFiles())
                {
                    certificateAlias = SSL_KEY_ALIAS + Integer.toString(index++);
                    try
                    {
                        inputStream = new FileInputStream(cerFile);
                        addOneCer(certificateFactory, keyStore, certificateAlias, inputStream);
                    }
                    catch (Exception e)
                    {
                        LogUtil.error(null, e);
                    }
                    finally
                    {
                        try
                        {
                            if (inputStream != null)
                                inputStream.close();
                        }
                        catch (IOException e)
                        {
                            LogUtil.error(null, e);
                        }
                    }
                }
            }
    
            return keyStore;
        }
    
        private void addOneCer(CertificateFactory certificateFactory, KeyStore keyStore, String CerAlias,
                InputStream certificate) throws KeyStoreException, CertificateException
        {
            keyStore.setCertificateEntry(CerAlias, certificateFactory.generateCertificate(certificate));
            try
            {
                if (certificate != null)
                    certificate.close();
            }
            catch (IOException e)
            {
                LogUtil.error(null, e);
            }
        }
    
        // 初始化普通请求
        private void initNormalClient()
        {
            // 进行数据初始化
            okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder().readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)// 设置读取超时时间
                    .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)// 设置写的超时时间
                    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);// 设置连接超时时间
            // 有证书需要引入
            if (null != sslSocketFactory && null != trustManager)
            {
                builder.sslSocketFactory(sslSocketFactory, trustManager);
            }
            if (IS_INORE_CA)
            {
                builder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            }
            mOkHttpClient = builder.build();
        }
    
        // 初始化快速请求
        private void initQuickClient()
        {
            okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .readTimeout(READ_TIMEOUT_QUICK, TimeUnit.SECONDS)// 设置读取超时时间
                    .writeTimeout(WRITE_TIMEOUT_QUICK, TimeUnit.SECONDS)// 设置写的超时时间
                    .connectTimeout(CONNECT_TIMEOUT_QUICK, TimeUnit.SECONDS);// 设置连接超时时间
    
            // 有证书需要引入
            if (null != sslSocketFactory && null != trustManager)
            {
                builder.sslSocketFactory(sslSocketFactory, trustManager);
            }
            if (IS_INORE_CA)
            {
                builder.hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            }
            mOkHttpClientQuick = builder.build();
        }
    
        // 初始化代理请求
        private void initProxyClient()
        {
            if (StringUtils.isEmpty(PROXY_IP))
            {
                return;
            }
            okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder().readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)// 设置读取超时时间
                    .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)// 设置写的超时时间
                    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);// 设置连接超时时间
    
            // 有证书需要引入
            if (null != sslSocketFactory && null != trustManager)
            {
                builder.sslSocketFactory(sslSocketFactory, trustManager);
            }
            builder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_IP, PROXY_PORT)));
            mOkHttpClientProxy = builder.build();
        }
    
        private String getCommon(String url, OkHttpClient okHttpClient, Map<String, String>[] params)
        {
            okhttp3.Request.Builder requestBuilder = createGetBuilder(url, params);
            return doSync(url, okHttpClient, requestBuilder, params);
        }
    
        /**
         * 异步请求
         * @param url
         * @param callback
         * @param mOkHttpClient
         * @param params
         * @exception/throws [异常类型] [异常说明](可选)
         * @date 2017年6月10日 下午5:05:06
         * @since 1.0.0
         */
        private void getCommonAsyn(String url, Callback callback, OkHttpClient mOkHttpClient, Map<String, String>[] params)
        {
            okhttp3.Request.Builder requestBuilder = createGetBuilder(url, params);
            doAsyn(url, callback, mOkHttpClient, requestBuilder, params);
        }
    
        private okhttp3.Request.Builder createGetBuilder(String url, Map<String, String>[] params)
        {
            String realUrl = url;
            Map<String, String> headers = null;
            if (null != params)
            {
                if (params.length > 0)
                {
                    realUrl = buildUrl(url, params[0]);
                }
                if (params.length > 1)
                {
                    headers = params[1];
                }
            }
    
            okhttp3.Request.Builder requestBuilder = createBuilder(realUrl, headers);
            return requestBuilder;
        }
    
        /**
         * 同步请求
         * @param url
         * @param okHttpClient
         * @param requestBuilder
         * @param params
         * @return
         * @exception/throws [异常类型] [异常说明](可选)
         * @date 2017年6月10日 下午5:04:29
         * @since 1.0.0
         */
        private String doSync(String url, OkHttpClient okHttpClient, okhttp3.Request.Builder requestBuilder,
                Map<String, String>[] params)
        {
            try
            {
                printRequestInfo(url, params);
    
                String response = okHttpClient.newCall(requestBuilder.build()).execute().body().string();
    
                printResponseInfo(response);
                return response;
            }
            catch (IOException e)
            {
                LogUtil.error("url:" + url + ",params:" + JsonTool.toJson(params), e);
            }
            return null;
        }
    
        private void printRequestInfo(String url, Map<String, String>[] params)
        {
            LogUtil.debug("url:" + url + "
     params:" + JsonTool.toJson(params).replace("\", ""));
        }
    
        private void printResponseInfo(String response)
        {
            LogUtil.debug("response:" + response);
        }
    
        /**
         * 异步请求
         * @param url
         * @param callback
         * @param okHttpClient
         * @param requestBuilder
         * @param params
         * @exception/throws [异常类型] [异常说明](可选)
         * @since 1.0.0
         */
        private void doAsyn(String url, Callback callback, OkHttpClient okHttpClient,
                okhttp3.Request.Builder requestBuilder, Map<String, String>[] params)
        {
            printRequestInfo(url, params);
            okHttpClient.newCall(requestBuilder.build()).enqueue(callback);
            // printResponseInfo(response);
        }
    
        private okhttp3.Request.Builder createBuilder(String url, Map<String, String> headers)
        {
            okhttp3.Request.Builder builder = new Request.Builder().url(url);
            if (null == headers)
            {
                return builder;
            }
    
            for (Map.Entry<String, String> en : headers.entrySet())
            {
                builder.addHeader(en.getKey(), en.getValue());
            }
            return builder;
        }
    
        private String buildUrl(String url, Map<String, String> param)
        {
            if (null == param)
            {
                return url;
            }
            StringBuilder sb = new StringBuilder();
            try
            {
                for (Map.Entry<String, String> en : param.entrySet())
                {
                    if (!StringUtils.isEmpty(en.getKey()) && !StringUtils.isEmpty(en.getValue()))
                    {
                        sb.append(PARAM_SPLIT);
                        sb.append(URLEncoder.encode(en.getKey(), DEFAULT_ENCODE));
                        sb.append(PARAM_SPLIT_VAL);
                        sb.append(URLEncoder.encode(en.getValue(), DEFAULT_ENCODE));
                    }
                }
            }
            catch (UnsupportedEncodingException e)
            {
                LogUtil.error("url=" + url, e);
            }
            if (sb.length() > 0)
            {
                if (!url.contains(PARAM_SPLIT_FIRST))
                {
                    url = url + PARAM_SPLIT_FIRST;
                }
                url = url + sb.substring(1);
            }
            return url;
        }
    
        private String postCommon(String url, OkHttpClient okHttpClient, Map<String, String>[] params)
        {
            okhttp3.Request.Builder requestBuilder = createPostBuilder(url, params);
            return doSync(url, okHttpClient, requestBuilder, params);
        }
    
        private void postCommonAsyn(String url, Callback callback, OkHttpClient okHttpClient, Map<String, String>[] params)
        {
            okhttp3.Request.Builder requestBuilder = createPostBuilder(url, params);
            doAsyn(url, callback, okHttpClient, requestBuilder, params);
        }
    
        private okhttp3.Request.Builder createPostBuilder(String url, Map<String, String>[] params)
        {
            Map<String, String> headers = null;
            Builder formBuilder = new FormBody.Builder();
            if (null != params)
            {
                if (params.length > 0 && null != params[0])
                {
                    for (Map.Entry<String, String> en : params[0].entrySet())
                    {
                        formBuilder.add(en.getKey(), en.getValue());
                    }
                }
    
                if (params.length > 1)
                {
                    headers = params[1];
                }
            }
            okhttp3.Request.Builder requestBuilder = createBuilder(url, headers).post(formBuilder.build());
            return requestBuilder;
        }
        
        /**
         * 文件上传
         * @param urlStore   上传服务地址
         * @param file       本地文件
         * @param callback   回调函数,若无则为同步,同步则直接返回result,异步则在callback中返回上传结果
         * @param params     第一个map为body中需要传的参数,第二个map为头文件中需要传的参数
         * @return
         * @exception/throws [异常类型] [异常说明](可选)
         * @date 2018年5月11日 上午8:47:24
         */
        public String upload(String urlStore, File file, Callback callback, Map<String, String>... params)
        {
            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream") , file);  
            okhttp3.MultipartBody.Builder mBodyBuilder = new MultipartBody.Builder()
                                                            .setType(MultipartBody.FORM)
                                                            .addFormDataPart("desc" , file.getName())
                                                            .addFormDataPart("file" , file.getName(), fileBody);
            Map<String, String> paramMap = null;
            if (null != params && params.length > 0)
            {
                paramMap = params[1];
            }                                                ;
            if (null != paramMap)
            {
                for (Map.Entry<String, String> en : paramMap.entrySet())
                {
                    mBodyBuilder.addFormDataPart(en.getKey(), en.getValue());
                }
            }
            Map<String, String> headMap = null;
            if (null != params && params.length > 1)
            {
                headMap = params[1];
            }
             
            okhttp3.Request.Builder requestBuilder = createBuilder(urlStore, headMap);
            requestBuilder.post(mBodyBuilder.build());
            
            if (null == callback)
            {
                //同步
                return doSync(urlStore, mOkHttpClient, requestBuilder, params);
            }
            else
            {
                //异步
                doAsyn(urlStore, callback, mOkHttpClient, requestBuilder, params);
                return null;
            }
        }
        
    
        
    }

    是否https证书验证(默认不做证书校验,建议生成环境一定要做证书校验,哪怕是导入私有证书),配置

    IS_INORE_CA = false

    导入私有证书,配置

    CA_PATH 配置CA证书(就是浏览器证书导出的那个证书)路径即可

    设置代理服务器,配置

    PROXY_IP和PROXY_PORT即可(默认不采用代理)

    上传文件

    String rs = HttpClientManage.getInstance().upload(urlStore, file, null, null);

    其中rs为同步返回的结果。

    OKHttp官网不建议使用多个实例,因为每个实例都自己配置了线程管理,所以项目中不涉及基础信息的改动(比如,超时时间,证书等),建议就共用一个实例。

  • 相关阅读:
    数据库
    Activity组件
    view,视图组件
    360导航板式
    service音乐播放
    service
    音乐播放器组件
    获取时间字符串
    JDK服务器存储
    数据库_黑名单练习_完善服务广播
  • 原文地址:https://www.cnblogs.com/zhuri/p/9022909.html
Copyright © 2011-2022 走看看