Background:
Recetly I would like to buy some MaoTais due to the poor life.Thus, it pushed me to learn about OKhtpp to discover the new land~
- Maven repository
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.10.0</version>
</dependency>
Maven also reminds me that I need to add another dependence to ensure it could run properly.
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.5.0</version>
Why Use It
OkHttp is an HTTP client that’s efficient by default:
- HTTP/2 support allows all requests to the same host to share a socket.
- Connection pooling reduces request latency (if HTTP/2 isn’t available).
- Transparent GZIP shrinks download sizes.
- Response caching avoids the network completely for repeat requests.
Create an instance
//use {@code final new OkHttpClient.Builder()} to create a singleton shared instance with custom settings:
final OkHttpClient client = new OkHttpClient.Builder().readTimeout(5,TimeUnit.SECONDS).build();
//for the Request, default method is #GET,if you want to use post,just.post(RequestBody body);
Request request = new Request.Builder().url(url).addHeader("Cookie", "$YouCoookie").addHeader("User-Agent", "$YourAgent").build();
During the study, there are some similar things between OkHttpClient & Request:
**OkHttpClient.Class interpreting **
/**
* Sets the default connect timeout for new connections. A value of 0 means no timeout,
* otherwise values must be between 1 and {@link Integer#MAX_VALUE} when converted to
* milliseconds.
*
* <p>The connectTimeout is applied when connecting a TCP socket to the target host.
* The default value is 10 seconds.
*/
public OkHttpClient.Builder connectTimeout(long timeout, TimeUnit unit) {
this.connectTimeout = Util.checkDuration("timeout", timeout, unit);
return this;
}
给新连接设置默认的超时时间,0代表没有超时;否则,值当被转化成秒时将会是0-int最大值之间。连接超时被用于一个TCP的Socket套接字连接到目标主机,默认值是10——即如果不设置的话。
注入此类的有很多
Builder的无参构造器
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
eventListenerFactory = EventListener.factory(EventListener.NONE);
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000; //默认10秒
readTimeout = 10_000;
writeTimeout = 10_000;
pingInterval = 0;
}
Builder的build方法,返回OkHttpClient的实例:
public OkHttpClient build() {
return new OkHttpClient(this);
}
- OkHttpClient的构造函数
而Okhttp的无参构造是去调用有参,且入参就为builder
//无参构造函数,调用this(builder)的有参构造函数
public OkHttpClient() {
this(new Builder());
}
//如参然后就是赋值,判断非空和blean类型
OkHttpClient(Builder builder) {
this.dispatcher = builder.dispatcher;
this.proxy = builder.proxy;
this.protocols = builder.protocols;
this.connectionSpecs = builder.connectionSpecs;
this.interceptors = Util.immutableList(builder.interceptors);
this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
this.eventListenerFactory = builder.eventListenerFactory;
this.proxySelector = builder.proxySelector;
this.cookieJar = builder.cookieJar;
this.cache = builder.cache;
this.internalCache = builder.internalCache;
this.socketFactory = builder.socketFactory;
boolean isTLS = false;
for (ConnectionSpec spec : connectionSpecs) {
isTLS = isTLS || spec.isTls();
}
if (builder.sslSocketFactory != null || !isTLS) {
this.sslSocketFactory = builder.sslSocketFactory;
this.certificateChainCleaner = builder.certificateChainCleaner;
} else {
X509TrustManager trustManager = systemDefaultTrustManager();
this.sslSocketFactory = systemDefaultSslSocketFactory(trustManager);
this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
}
this.hostnameVerifier = builder.hostnameVerifier;
this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
certificateChainCleaner);
this.proxyAuthenticator = builder.proxyAuthenticator;
this.authenticator = builder.authenticator;
this.connectionPool = builder.connectionPool;
this.dns = builder.dns;
this.followSslRedirects = builder.followSslRedirects;
this.followRedirects = builder.followRedirects;
this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
this.connectTimeout = builder.connectTimeout;
this.readTimeout = builder.readTimeout;
this.writeTimeout = builder.writeTimeout;
this.pingInterval = builder.pingInterval;
if (interceptors.contains(null)) {
throw new IllegalStateException("Null interceptor: " + interceptors);
}
if (networkInterceptors.contains(null)) {
throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
}
}
Request.Class interpreting
最后.build方法,将builder送回成Request;
//注意 这是内部静态类Builder的方法,生成Request对象
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
//return 其实是用实例化Request,入参为builder,将属性再赋值过去
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build(); //headers的build方法,返回一个新heards对象
this.body = builder.body;
this.tag = builder.tag != null ? builder.tag : this;
}
Difference between Header() & addHear()
/**
* Sets the header named {@code name} to {@code value}. If this request already has any headers
* with that name, they are all replaced.
*/
public Builder header(String name, String value) {
headers.set(name, value);
return this;
}
/**
* Adds a header with {@code name} and {@code value}. Prefer this method for multiply-valued
* headers like "Cookie".
*
* <p>Note that for some headers including {@code Content-Length} and {@code Content-Encoding},
* OkHttp may replace {@code value} with a header derived派生的 from the request body.
*/
public Builder addHeader(String name, String value)