OKHttp3初始化与配置

来源:互联网 发布:mac客户端的网游 编辑:程序博客网 时间:2024/06/19 06:08

OKHttp3初始化与配置

OKhttp在使用时,最基本的组成部分是OkHttpClient、Request、Call和Response,需要进行初始化的主要是OkHttpClient和Request。

  • OKHttp3初始化与配置
    • OKHttpClient
      • 常用配置项
      • Https配置
      • 拦截器
      • 其他设置
    • Request
    • 参考资料

OKHttpClient

一般情况下,全局只需一个OkHttpClient实例(强烈建议),便可以满足整个应用的Http请求,其主要是由OkHttpClient.Builder的建造者模式来进行配置和初始化的,如可创建一个用于普通http请求的公用OkHttpClient实例:

OkHttpClient okHttpClient = new OkHttpClient.Builder().build();

也可以创建定制化的实例:

OkHttpClient customClient = okHttpClient.newBuilder().readTimeout(10000, TimeUnit.MILLISECONDS).build();

定制化的OkHttpClient与原实例共享连接池、线程池和公共配置项。OkHttpClient的配置项位于build方法前。

常用配置项

OkHttpClient client = new OkHttpClient.Builder()        .connectTimeout(60, TimeUnit.SECONDS)      //设置连接超时        .readTimeout(60, TimeUnit.SECONDS)         //设置读超时        .writeTimeout(60, TimeUnit.SECONDS)        //设置写超时        .retryOnConnectionFailure(true)            //是否自动重连        .build();  

Https配置

对于https(此处可简单复习一下https简单原理),需要配置sslSocketFactory,一般如需忽略所有证书的话,可以这样配置:

client = new OkHttpClient.Builder()        // 设置https配置,此处忽略了所有证书        .sslSocketFactory(createEasySSLContext().getSocketFactory(), new EasyX509TrustManager(null))          .build();  
private static SSLContext createEasySSLContext() throws IOException {    try {        SSLContext context = SSLContext.getInstance("TLS");        context.init(null, null, null);        return context;    } catch (Exception e) {        throw new IOException(e.getMessage());    }}
public class EasyX509TrustManager implements X509TrustManager {    private X509TrustManager standardTrustManager = null;    /**     * Constructor for EasyX509TrustManager.     */    public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException,            KeyStoreException {        super();        TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory                .getDefaultAlgorithm());        factory.init(keystore);        TrustManager[] trustmanagers = factory.getTrustManagers();        if (trustmanagers.length == 0) {            throw new NoSuchAlgorithmException("no trust manager found");        }        this.standardTrustManager = (X509TrustManager)trustmanagers[0];    }    /**     * @see X509TrustManager#checkClientTrusted(X509Certificate[],     *      String authType)     */    public void checkClientTrusted(X509Certificate[] certificates, String authType)            throws CertificateException {        standardTrustManager.checkClientTrusted(certificates, authType);    }    /**     * @see X509TrustManager#checkServerTrusted(X509Certificate[],     *      String authType)     */    public void checkServerTrusted(X509Certificate[] certificates, String authType)            throws CertificateException {        if ((certificates != null) && (certificates.length == 1)) {            certificates[0].checkValidity();        } else {            standardTrustManager.checkServerTrusted(certificates, authType);        }    }    /**     * @see X509TrustManager#getAcceptedIssuers()     */    public X509Certificate[] getAcceptedIssuers() {        return this.standardTrustManager.getAcceptedIssuers();    }}

此外还可以使用以下代码忽略本地校验url正确性:

.hostnameVerifier(new HostnameVerifier() {    @Override    public boolean verify(String hostname, SSLSession session) {        return true;    }})  // 验证服务器的证书域名。在https握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口的实现程序来确定是否应该允许此连接

拦截器

拦截器有两种,应用拦截器和网络拦截器:
Okhttp3拦截器
详细的拦截器分析说明可见此处,我们最常使用的拦截器就是网络日志打印功能了:

.addInterceptor(new Interceptor() {    @Override    public Response intercept(Chain chain) throws IOException {        Request request = chain.request();        Log.d("intercept",  "接口地址:" + request.url()                    + "\r\n接口参数(这里一般不直接toString,body里的是stream):" + request.body().toString());        }        return chain.proceed(chain.request());    }}) // 日志记录

其他与https相关的配置项(以下可忽略,一般不用设置,纯当笔记,摘自此处):

.certificatePinner(new CertificatePinner.Builder()        .add("test1.com", "sha1/sdfsdsdsdsdsdsdsdsdsdsdds=")        .add("test2.com", "sha1/sdsdsdsdsdsdsdsdsdssdssds=")        .build()) // 添加证书,一般不要设置

添加受信证书,最好不要去设置,详见此处。

.connectionSpecs(...) // 设置连接的规格、TLS版本和密码套件等

其他设置

.socketFactory(new SocketFactory() {...}) // 使用定制的用于http请求的套接字
.authenticator(new Authenticator() {    @Override    public Request authenticate(Route route, Response response) throws IOException {        ...    }}) // 添加授权证书

通过Authenticator类,可以响应来自远程或者代理服务器的授权验证,通常情况会返回一个授权头以做验证;亦或是返回空表示拒绝验证。简单来说,你要访问一个服务,但是你要对方的验证。通过Authenticator类来代理一个认证请求,并使用Credentials.basic()来构造一个证书。

.cache(new Cache(new File("cache.tmp"), 10 * 1024 * 1024)) // 10M缓存
.connectionPool(new ConnectionPool(5, 6, TimeUnit.MINUTES))// 定义连接池,最多有五个空闲连接,每个空闲连接最多保持6分钟

OkHttp使用共享连接池,默认为5个5分钟空闲的连接池。

.cookieJar(new CookieJar() {    @Override    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {        // response时保存cookie    }    @Override    public List<Cookie> loadForRequest(HttpUrl url) {        // request发送前,将cookie加到request中        return ...;    }}) // cookie保存和使用

若需要持久化cookie,此篇文章可以借鉴。

.dispatcher(new Dispatcher(new ThreadPoolExecutor(...)))// 指定分发器,即异步执行http请求时的线程池,http响应的回调也是在此线程池的线程中执行
.dispatcher(new Dispatcher(new ThreadPoolExecutor(...)))// 指定分发器,即异步执行http请求时的线程池,http响应的回调也是在此线程池的线程中执行
.followRedirects(true)       // 允许http重定向.followSslRedirects(false)   // 截断https的重定向

这两个都是设置是否进行链接重定向的。设置为false时,可以截断重定向。在一些无限循环重定向的链接情况下,通过截断重定向,并在Call的onResponse中自行处理重定向,可以解决此问题。

.pingInterval(30, TimeUnit.SECONDS) // 设置ping检测网络连通性的间隔。默认为0
.protocols()  // 设置使用的协议,目前支持http1.1和http2,不能包含空和http1.0。一般不会设置
.proxy(...) // 设置单个代理.proxyAuthenticator(...)  // 设置代理验证.proxySelector(...) // 为不同的链接设置不同的代理

Request

Request也如okhttpclient一样使用构造者模式生成、复用属性,其主要由四部分组成:
这里写图片描述
Method就是http支持的head、post、get、delete、put、patch:

Request request = new Request.Builder()        .head()        .post(requestBody)        .get()        .delete().delete(requestBody)        .put(requestBody)        .patch(requestBody)        .method(“post”, requestBody)

Body主要用于post、delete、put、patch时的内容,如提交json字符串:

MediaType JSON = MediaType.parse("application/json; charset=utf-8");RequestBody rb = RequestBody.create(JSON, jsonString);

Url即指定链接:

.url("http://www.baidu.com").url(HttpUrl.parse("http://www.baidu.com")).url(new HttpUrl.Builder(). ... .build());

Header可以设置请求的头:

.addHeader("sd", "dsds") // 添加头部,不会覆盖旧值.header("fd", "sdasd")   // 替换相同name的值.removeHeader("fd")      // 删除头部

其他常用设置有:
缓存,针对单个请求:

final CacheControl.Builder builder = new CacheControl.Builder();builder.noCache();       // 不使用缓存,全部走网络builder.noStore();       // 不使用缓存,也不存储缓存builder.onlyIfCached();  // 只使用缓存builder.noTransform();   // 禁止转码builder.maxAge(10, TimeUnit.SECONDS);   // 能接收10秒内的缓存builder.maxStale(10, TimeUnit.SECONDS); // 指示客户机可以接收超出超时期间的响应消息,即过期后的10秒内缓存可以继续使用,cache的响应头部会有提示builder.minFresh(10, TimeUnit.SECONDS);// 至少在10秒内,缓存要保持更新CacheControl cache = builder.build();xxxRequestBuilder.cacheControl(cache)
.tag("asdsad") // 设置tag,可以用于标记每个request等

参考资料

OKHttp3.0的日常及入门
OkHttp3之Cookies管理及持久化
Class CertificatePinner
square/okhttp的https配置
OkHttp之拦截器
HTTPS工作原理和TCP握手机制

原创粉丝点击