OkHttp3简单使用教程(一):请求和响应
https://www.jianshu.com/p/f3f228d3598c
\n
HTTP请求报文主要由请求行、请求头部、请求正文3部分组成.
请求行:由请求方法,URL,协议版本三部分构成,之间用空格隔开
请求 Content-Language
请求zhengwen
/n
23 URL带的参数
HTTP响应报文格式:
HTTP响应报文主要由状态行、响应头部、响应正文3部分组成
HTTP响应报文主要由状态行、响应头部、响应正文3部分组成
Content-Charset
由3部分组成,分别为:协议版本,状态码,状态码描述,之间由空格分隔
OkHttpClient Request .url.build
newCall
.enquene
onResponse
HttpUrl.Builder newBuilder
params.keySet
setQueryParameter key,params.get key
.url .headers .get .build
//同步
Response response = call.execute()
if(response.isSuccessful()){
//响应成功
}
.post urlBuilder.build
httpClient.newCall request
Call call
//URL带的参数
HashMap<String,String> params = new HashMap<>();
//GET 请求带的Header
HashMap<String,String> headers= new HashMap<>();
Request request = new Request.Builder()
.url(urlBuilder.build())
.headers(headers == null ? new Headers.Builder().build() : Headers.of(headers))
// 构造Request->call->执行
Request request = new Request.Builder()
.headers(extraHeaders == null ? new Headers.Builder().build() : Headers.of(extraHeaders))//extraHeaders 是用户添加头
.url(url)
.post(urlBuilder.build())//参数放在body体里
MultipartBody.Builder RequestBody Request
OkHttp POST
sink.write content
RequestBody
HTTP响应报文格式:
HTTP响应报文主要由状态行、响应头部、响应正文3部分组成
HTTP请求报文格式:
HTTP请求报文主要由请求行、请求头部、请求正文3部分组成.
Http请求中Content-Type
Content-Type
MultiPartBody的BufferedSink
MediaType Part
contentLength
sink
body
/Part 的定义,Part 是由Headers+RequestBody组成
OKHttp源码解析
https://www.cnblogs.com/zn615/p/8182304.html
part/
OkHttpClient build
newCall0
getResponseWithInterceptorChain
interceptors
Request url method header body
excute
OkHttpClient
Dispatcher Protocol ConnectionSpec
ConnectionPool
Interceptor
Interceptor.Chain
InternalCache
resources
看到这,如果你还不明白的话,也没关系,在OkHttp中只是设置用的的各个东西。真正的流程要从里面的newCall()方法中说起:
/**
* Prepares the {@code request} to be executed at some point in the future.
* 准备将要被执行的request
*/
@Override
public Call newCall(Request request) {
return new RealCall(this, request);
}
client.newCall(re)
Response response = client.newCall(request).execute();这就代码就开启了整个GET请求的流程:
client.dispatcher.execute this
client.dispatcher.finished
getResponseWithInterceptorChain
用 getResponseWithInterceptorChain() 函数获取 HTTP 返回结果,从函数名可以看出,这一步还会进行一系列“拦截”操作。
//拦截器的责任链。
RealInterceptorChain next = RealInterceptorChain
interceptors
Response response =
interceptor.intercept(next);
Request.Builder
responseBuilder.build
ConnectInterceptor;
realChain.request
realChain.streamAllocation
realChain.proceed request,streamAllocation,httpCodec,connection
NetworkInterceptors
CallServerInterceptor httpStream .streamAllocation
chain.request
HttpCodec.request
OkHttpClient request
client.newCall request .enqueue
onResponse
resource.headers非必须
client.dispatcher.enquene AsyncCall
Dispatcher enquene Call
client.dispatcher.finished this
Response response = getResponseWithInterceptorChain();
OkHttpClient Builder
build
OkHttpClient
newCall
RealCall
execute enquene
Dispatcher
intercepters
originalRequest getResponseWithInterceptorChain
CacheInterceptor
ConnectInterceptor
networkInterceptors
CallServerInterceptor
Request url method header body
Response code message headers非必须 body
在配置 OkHttpClient 时设置的 interceptors;
负责失败重试以及重定向的 RetryAndFollowUpInterceptor;
负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应的 BridgeInterceptor;
负责读取缓存直接返回、更新缓存的 CacheInterceptor;
负责和服务器建立连接的 ConnectInterceptor;
配置 OkHttpClient 时设置的 networkInterceptors;
负责向服务器发送请求数据、从服务器读取响应数据的 CallServerInterceptor。
在return chain.proceed(originalRequest);中开启链式调用:
chain.proceed originalRequest
//3,新建一个call对象
Call call = mOkHttpClient.newCall(request);
//4,请求加入调度,这里是异步Get请求回调
call.enqueue(new Callback()
newCall enquene
Request .url
call.excute call.enquene call.cancel
MultipartBody.Builder urlBuilder = new MultipartBody.Builder()
.setType(MultipartBody.FORM);
MultiPartBody.Builder MultiPartBody.FORM
addFormDataPart
.post(urlBuilder.build())//参数放在body体里
urlBuilder.setQueryParameter(key, params.get(key));
setQueryParameter
.url(urlBuilder.build())
RequestBody = contentType + BufferedSink + RequestBody
/** Writes the content of this request to {@code sink}. */
//写入缓存sink
public abstract void writeTo(BufferedSink sink) throws IOException;
writeTo BufferedSink sink
charset contentType MediaType
new RequestBody
//文件写入BufferedSink
source = Okio.source(file);
sink.writeAll(source);
sink.writeAll
Http请求中Content-Type
MediaType FORM multipart/form-data
、 Part part = parts.get(p);
//Part的Headers和RequestBody
Headers headers = part.headers;
RequestBody body = part.body;
part.headers非必须
part.body
return new Part(headers, body);
createFormData
Part.create body
Headers headers RequestBody body
重点:RequestBody create(MediaType contentType, final File file)构造文件请求体RequestBody ,并且添加到MultiPartBody中
multipart/form-data
MultipartBody.Builder urlBuilder=
new MultipartBody.Builder().
setType(MultipartBody.FORM);
files.keySet
RequestBody.create(MediaType.parse("multipart/form-data"), files.get(key))
addFormDataPart
url post newCall0 request.enquene
onResponse
MultiPartBody Headers body
RequestBody
SparseArray<FileBlock>
对文件块分块多线程异步上传
url domain/sync/img/upload
method POST
data = {
}
ExcutorService threadPool = ExcutorService.newCachedThreadPool
while ((len = in.read(buf)) >= 0 && nowSeek < seekEndWrite) {
sink.write(buf, 0, len);
sink.write buf,0,len
//组装其它参数
MultipartBody.Builder urlBuilder = new MultipartBody.Builder()
.setType(MultipartBody.FORM);
MultiPartBody.Builder
//把文件块的请求体添加到MultiPartBody中
urlBuilder.addFormDataPart(fileKey, file.getName(), requestBody);
url post build
httpClient.newCall request