okhttp 使用总结

okhttp 的使用越来越火,有必要对其进行研究。以下博客中的例子为了简单,在Eclipse中通过JAVA工程进行验证。

导入OkHttp

AndroidStudio

添加如下代码即可

 compile 'com.squareup.okhttp3:okhttp:3.3.1'compile 'com.squareup.okio:okio:1.8.0'

其中okiookhttp中关于流的操作。必须导入。

Eclipse

导入okhttpokio的jar包即可。

下载地址okhttp3.3.1与okio-1.8.0

同步的GET请求

主要分为以下几步:

  • 创建OkHttpClient对象
  • 根据需求创建Request对象,Request中主要包含了请求的url,参数等信息。
  • 通过request对象创建Call对象
  • 使用call对象进行网络请求。返回封装好的Response
  • 解析Response对象,获取响应信息
/**
*  同步 Get 请求
*/
public static void syncGet() throws Exception {// 1. 创建`OkHttpClient`对象final OkHttpClient client = new OkHttpClient();// 2.根据需求创建`Request`对象.在此只是添加了最基本的urlRequest request = new Request.Builder().url(BAIDU_MP3_PATH).build();// 3.通过`request`对象创建`Call`对象Call call = client.newCall(request);// 4.使用`call`对象进行网络请求。返回封装好的`Response`Response response = call.execute();// 5.解析`Response`对象,获取响应信息if (!response.isSuccessful())// code >= 200 && code < 300;System.out.println(response);Headers responseHeaders = response.headers();for (int i = 0; i < responseHeaders.size(); i++) {System.out.println(responseHeaders.name(i) + ":"+ responseHeaders.value(i));}// 打印响应的内容System.out.println(response.body().string());}

其中使用的url为百度MP3的接口:

http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=1&offset=0&size=1

看一下打印结果:


//---- response 的toString() 默认打印的信息  响应行
Response{protocol=http/1.1, code=200, message=OK, url=http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=1&offset=0&size=1}//----- 响应的头
Date:Wed, 29 Jun 2016 01:51:39 GMT
Content-Type:application/json
Transfer-Encoding:chunked
Connection:keep-alive
X-LIGHTTPD-LOGID:427084050
RT:427084050_d41d8cd98f00b204e9800998ecf8427e_d41d8cd98f00b204e9800998ecf8427e
Server:Apache1.0
SC:MISS.0.0
tracecode:30991485713674384576062909
Set-Cookie:BAIDUID=B343E34EB3618E7E2E867A6E1D4F04EB:FG=1; expires=Thu, 29-Jun-17 01:51:39 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1
P3P:CP=" OTI DSP COR IVA OUR IND COM "// ---- 响应的内容  body
{"song_list":[{"artist_id":"247010469","language":"\u56fd\u8bed","pic_big":"http:\/\/musicdata.baidu.com\/data2\/pic\/0c87cb20fd6b543cd1c90d1d82f1f6c5\/266782982\/266782982.jpg","pic_small":"http:\/\/musicdata.baidu.com\/data2\/pic\/169cbb0d82522568dea198363f7028ec\/266782985\/266782985.jpg","country":"\u5185\u5730","area":"0","publishtime":"2016-06-20","album_no":"1","lrclink":"http:\/\/musicdata.baidu.com\/data2\/lrc\/1f75306d7f1e25f723d3d175f5ef3d46\/266791084\/266791084.lrc","copy_type":"1","hot":"276927","all_artist_ting_uid":"232954914","resource_type":"0","is_new":"1","rank_change":"0","rank":"1","all_artist_id":"247010469","style":"\u6d41\u884c","del_status":"0","relate_status":"0","toneid":"0","all_rate":"64,128,256","sound_effect":"0","file_duration":0,"has_mv_mobile":1,"versions":"","bitrate_fee":"{\"0\":\"0|0\",\"1\":\"-1|-1\"}","song_id":"266784254","title":"\u7ea2","ting_uid":"232954914","author":"\u51af\u5efa\u5b87","album_id":"266784256","album_title":"\u7ea2","is_first_publish":0,"havehigh":0,"charge":0,"has_mv":1,"learn":0,"song_source":"web","piao_id":"0","korean_bb_song":"1","resource_type_ext":"1","mv_provider":"0100000000","artist_name":"\u51af\u5efa\u5b87"}],"billboard":{"billboard_type":"1","billboard_no":"1871","update_date":"2016-06-28","billboard_songnum":"190","havemore":1,"name":"\u65b0\u6b4c\u699c","comment":"\u8be5\u699c\u5355\u662f\u6839\u636e\u767e\u5ea6\u97f3\u4e50\u5e73\u53f0\u6b4c\u66f2\u6bcf\u65e5\u64ad\u653e\u91cf\u81ea\u52a8\u751f\u6210\u7684\u6570\u636e\u699c\u5355\uff0c\u7edf\u8ba1\u8303\u56f4\u4e3a\u8fd1\u671f\u53d1\u884c\u7684\u6b4c\u66f2\uff0c\u6bcf\u65e5\u66f4\u65b0\u4e00\u6b21","pic_s640":"http:\/\/c.hiphotos.baidu.com\/ting\/pic\/item\/f7246b600c33874495c4d089530fd9f9d62aa0c6.jpg","pic_s444":"http:\/\/d.hiphotos.baidu.com\/ting\/pic\/item\/78310a55b319ebc4845c84eb8026cffc1e17169f.jpg","pic_s260":"http:\/\/b.hiphotos.baidu.com\/ting\/pic\/item\/e850352ac65c1038cb0f3cb0b0119313b07e894b.jpg","pic_s210":"http:\/\/business.cdn.qianqian.com\/qianqian\/pic\/bos_client_c49310115801d43d42a98fdc357f6057.jpg","web_url":"http:\/\/music.baidu.com\/top\/new"},"error_code":22000}

如果熟悉HTTP 协议的可知,作为Http的响应,分为响应行,响应头,响应体。

如果不熟悉HTTP协议,欢迎看我之前的博客Java Web之HTTP协议总结

如上打印结果就分别对应了响应行,响应头,响应体。

注释很清楚,按照步骤即可,着重提一下解析Response的内容。

  • response.isSuccessful(),该方法在响应code为[200,300)时,返回true,其余返回false。注意区间为前闭后开。
  • response.headers():获取响应行信息的所有参数的集合headersheaders的使用方式类似于List
  • response.body().string():该方法返回的是响应的内容。但是,官方给出的指导是,如果响应的内容大于1MB 时,不建议使用该方法。因为该方法会将内容全部加载到内存中。推荐使用流的方式获取加载的数据。
    • response.body().byteStream();:字节输入流
    • response.body().charStream();:字符输入流

异步的GET 请求

异步GET的请求方式几乎和上面的步骤类似,唯一的区别是通过Call对象请求网络时,不在直接返回Response对象,而是通过接口回调的方式获取数据。当然,表面上是这样,其内部肯定有对应的线程切换。

/*** 异步的get方法*/public static void asyncGet() throws Exception {// 1. 创建`OkHttpClient`对象final OkHttpClient client = new OkHttpClient();// 2.根据需求创建`Request`对象.在此只是添加了最基本的urlRequest request = new Request.Builder().url(BAIDU_MP3_PATH).build();// 3.通过`request`对象创建`Call`对象Call call = client.newCall(request);// 4.使用`call`对象进行网络请求。通过Callback 监听网络请求call.enqueue(new Callback() {public void onResponse(Call call, Response response)throws IOException {//5, 获取响应结果并解析if (!response.isSuccessful()) {System.out.println(response);return;}Headers responseHeaders = response.headers();for (int i = 0, size = responseHeaders.size(); i < size; i++) {System.out.println(responseHeaders.name(i) + ": "+ responseHeaders.value(i));}System.out.println(response.body().string());}public void onFailure(Call call, IOException e) {System.out.println(e);}});}

此时我们使用了call.enqueue()方法,并通过Callback对象监听回调,其中Callback对象中包含了两个回调方法,成功onResponse和失败onFailure

肯定会有人说,我擦~~onResponse()中为什么还要判断response.isSuccessful(),不是已经成功了吗。

在这里这两个方法的含义和其他框架的有区别。

在这贴上该方法的注释就明白了

/*** Called when the request could not be executed due to cancellation, a connectivity problem or* timeout. Because networks can fail during an exchange, it is possible that the remote server* accepted the request before the failure.*/void onFailure(Call call, IOException e);/*** Called when the HTTP response was successfully returned by the remote server. The callback may* proceed to read the response body with {@link Response#body}. The response is still live until* its response body is {@linkplain ResponseBody closed}. The recipient of the callback may* consume the response body on another thread.** <p>Note that transport-layer success (receiving a HTTP response code, headers and body) does* not necessarily indicate application-layer success: {@code response} may still indicate an* unhappy HTTP response code like 404 or 500.*/void onResponse(Call call, Response response) throws IOException;

有能力的自己翻译,我是这样理解的。

  • onResponse() :连接上了服务器,不管服务器是否有资源(404)或者服务器出bug了(500)。
  • onFailure(): 没有连接上服务器。(域名不存在,无网络。。。)

设置和获取响应行参数(Header)

HTTP 协议中,无论对请求和响应,都有相应的头参数。一些特别的参数能够完成一些特别的任务。类似缓存,传输编码,重定向等等。

我们知道头信息中的参数类似于Map<String,String>,键值对的形式,但是有些特殊的头,不是一对一的,而是一对多。那么此时okHttp肯定要有特别的方法获取这些信息。

public void accessHeader() throws Exception {final OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://api.github.com/repos/square/okhttp/issues")// 只有一个参数的头  ,一对一,如果在添加会覆盖.header("User-Agent", "OkHttp Headers.java")// 一对多,添加的关系.addHeader("Accept", "application/json; q=0.5").addHeader("Accept", "application/vnd.github.v3+json").build();Response response = client.newCall(request).execute();if (!response.isSuccessful())throw new IOException("Unexpected code " + response);System.out.println("Server: " + response.header("Server"));System.out.println("Date: " + response.header("Date"));// 一对多的获取System.out.println("Vary: " + response.headers("Vary"));}

添加请求头信息时分为两种情况:
- 一对一: 使用header(String key,String value)方法,相同的key值调用此方法,会覆盖之前的value。
- 一对多: 使用addHeader(String key,String value)方法,相同的key值调用此方法,执行追加操作。

获取响应头信息时:

  • 一对一: 使用header(String key)方法。
  • 一对多: 使用headers(String key)方法。

POST 请求,传入一个字符串

Post请求,在构造Request时,传入POST的参数即可。

public static void postString() throws Exception {// post 传参类型 编码final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");// post 参数值String params = "### 三级标题";final OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://api.github.com/markdown/raw").post(RequestBody.create(MEDIA_TYPE_MARKDOWN, params)).build();Response response = client.newCall(request).execute();if (!response.isSuccessful())throw new IOException("Unexpected code " + response);System.out.println(response.body().string());}

Request.post中传入的是RequestBody对象,该对象的创建需要两个参数

  • MediaType contentType:传入参数的类型。通常使用的是text/html; chareset=utf-8。明白此值的含义,其实就是理解HTTP 协议中content-type的作用:决定浏览器/服务器将以什么形式、什么编码读取这个文件。
  • String content:post发送的内容。

在此,参数类型使用的是text/x-markdown; charset=utf-8,因为是调用github 的markdown的解析服务。所以传入了特定的类型。

返回结果

<h3>
<a id="user-content-三级标题" class="anchor" href="#%E4%B8%89%E7%BA%A7%E6%A0%87%E9%A2%98" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>三级标题</h3>

可见已经解析成了html 语言。

POST 文件

传入文件就是在RequestBody.creat()中,第二个参数传入一个file对象。

 /*** 传入文件*/public static void postFile() throws Exception{final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");final OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://api.github.com/markdown/raw").post(RequestBody.create(MEDIA_TYPE_MARKDOWN,new File("README.MD"))).build();// ....}

看看create方法,对于文件干了什么。

    new RequestBody() {@Override public MediaType contentType() {return contentType;}@Override public long contentLength() {return file.length();}@Override public void writeTo(BufferedSink sink) throws IOException {Source source = null;try {// ---- 读取文件source = Okio.source(file);sink.writeAll(source);} finally {Util.closeQuietly(source);}}};

该方法中,根据传入的参数创建了一个RequestBody对象,其中writeTo中读取了文件,source = Okio.source(file);square封装的io操作库。继续深入

public static Source source(File file) throws FileNotFoundException {if (file == null) throw new IllegalArgumentException("file == null");// --- 字节输入流,读取文件return source(new FileInputStream(file));}

看到这里,就明白了,其实就是通过字节输入流,去读取文件。中间有加了基层流的转换,暂时不管。

POST form 表单(日常使用)

如上的例子中,使用RequestBody.create()方法作为post的参数,很是麻烦。如果对于日常使用的post请求,需要些很多代码。那么理所当然的会有其子类替我们封装了这些方法。

FormBodyReqeustBody的子类,主要用于常见的表单操作。

    /*** post form 表单*/public static void postForm(){RequestBody formBody = new FormBody.Builder().add("name","1234").build();final OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("https://api.github.com/markdown/raw").post(formBody).build();// .....}

通过add(String key,String value)方法添加参数即可。

POST 实现复杂的form表单提交(上传文件)

在开发,往往会有上传用户头像等的需求,即复杂的表单。此时可以使用RequestBody的子类MultipartBody实现。

 /*** 提交复杂的form 表单 附带文件**  MultiBody*/public static void postMultipart(){/*** 上传的文件类型*/final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");/*** 参数*/RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("title","标题").addFormDataPart("image","logo.png",RequestBody.create(MEDIA_TYPE_PNG,new File("xx.png"))).build();Request request = new Request.Builder().url("xxx").post(requestBody).build();// ......}

Cache 缓存的实现

OkHttpClient可以实现缓存,但如果我们不做任何配置(设置缓存的目录),则是没有缓存的。

看下面的例子

        OkHttpClient client = new OkHttpClient.Builder().build();Request request = new Request.Builder().url("http://xxxx/login.txt")//.cacheControl(new CacheControl.Builder().noCache().build()).build();Response response1 = client.newCall(request).execute();String response1Body = response1.body().string();// 响应的结果信息System.out.println("Response 1 response:          " + response1);// 缓存的响应信息System.out.println("Response 1 cache response:    "+ response1.cacheResponse());// 网络请求的响应信息System.out.println("Response 1 network response:  "+ response1.networkResponse());// ************第二次请求******************  Response response2 = client.newCall(request).execute();String response2Body = response2.body().string();System.out.println("Response 2 response:          " + response2);System.out.println("Response 2 cache response:    "+ response2.cacheResponse());System.out.println("Response 2 network response:  "+ response2.networkResponse());System.out.println("Response 2 equals Response 1? "+ response1Body.equals(response2Body));

进行了两次请求,在请求之后,分别打印三个结果
- response:最终的响应
- cacheResponse: 缓存的响应,如果是从缓冲中取的,则该值不为null。
- networkResponse:网络请求的响应,如果是从网络中请求的,则该值不为null。

Response 1 response:          Response{protocol=http/1.1, code=200, message=OK, url=http://xxx/login.txt}
Response 1 cache response:    null
Response 1 network response:  Response{protocol=http/1.1, code=200, message=OK, url=http://xxx/login.txt}
Response 2 response:          Response{protocol=http/1.1, code=200, message=OK, url=http://xxx/login.txt}
Response 2 cache response:    null
Response 2 network response:  Response{protocol=http/1.1, code=200, message=OK, url=http://xxx/login.txt}
Response 2 equals Response 1? true

会发现cache response一直为null,而network response 一直不为null。可见使用了缓存。

修改代码,添加缓存

        // 缓存的大小int cacheSize = 10 * 1024 * 1024; // 10 MiB// 缓存对象,第一个参数为缓存的目录Cache cache = new Cache(new File("cache"), cacheSize);// 设置缓存OkHttpClient client = new OkHttpClient.Builder().cache(cache).build();//.....

通过构造Cache对象并对OkHttpClient设置。

Response 1 response:          Response{protocol=http/1.1, code=200, message=OK, url=http://xxx/login.txt}
Response 1 cache response:    null
Response 1 network response:  Response{protocol=http/1.1, code=200, message=OK, url=http://xxx/login.txt}
Response 2 response:          Response{protocol=http/1.1, code=200, message=OK, url=http://xxx/login.txt}
Response 2 cache response:    Response{protocol=http/1.1, code=200, message=OK, url=http://xxx/login.txt}
Response 2 network response:  null
Response 2 equals Response 1? true

第一次请求时,缓存为null,网络请求不为null。因为初次加载,并没有缓存。

第二次时,网络请求为null。缓存不为null。直接从之前保存的缓存中获取值。

当然。此时是对所有的request设置是否缓存,同时我们可以对每一个request设置独属于自己的缓存。

        // 不缓存Request request = new Request.Builder().url("http://xxx/login.txt").cacheControl(new CacheControl.Builder().noCache().build()).build();

通过cacheControl()传入一个缓存的配置对象,

  • 不使用缓存:new CacheControl.Builder().noCache().build()
  • 设置缓存的时长:new CacheControl.Builder().maxAge().build()
    • maxAge(int maxAge, TimeUnit timeUnit): 时间数值,单位。

取消网络请求

当一个页面结束时,往往要结束网络请求,此时可以通过Call.cancel()取消一个网络请求。这样做有利于节省系统资源。如果结束时,当前正在请求或响应,则会抛出一个IOException

也可以取消多个网络请求。

当构建请求时,使用RequestBuilder.tag(tag)对当前请求设置一个标签。之后通过OkHttpClient.cancel(tag)取消对应标签的请求。

超时的设置

连接超时,写入超时,读取超时是网络访问中常见的超时。

OkHttpClient  client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)// 连接超时 10s.writeTimeout(10, TimeUnit.SECONDS) // 输入超时 10s.readTimeout(30, TimeUnit.SECONDS) // 读取超时  30s.build();

该方式是设置全局的超时规则,同样我们也可以对于不同的情况设置不同的超时选项。

关键点: 通过OkHttpClient.newBuilder()构造一个client的复制体。注意,此复制类似于从client 扣下来一块设置不同的规则,同时复制体上设置的规则不会影响原client

/*** 设置不同的超时时间*/public static void singleTimeOut() throws Exception {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("http://xxxx").build();try {// 从client 中抠出一小块,用于单独的设置// 设置读取时间为1ms,肯定会超时OkHttpClient copy = client.newBuilder().readTimeout(1, TimeUnit.MILLISECONDS).build();Response response = copy.newCall(request).execute();System.out.println("Response 1 succeeded: " + response);} catch (IOException e) {System.out.println("Response 1 failed: " + e);}try {// 从client 中抠出一小块,用于单独的设置// 设置读取时间为3000msOkHttpClient copy = client.newBuilder().readTimeout(3000, TimeUnit.MILLISECONDS).build();Response response = copy.newCall(request).execute();System.out.println("Response 2 succeeded: " + response);} catch (IOException e) {System.out.println("Response 2 failed: " + e);}}

结果

Response 1 failed: java.net.SocketTimeoutException: Read timed outResponse 2 succeeded: Response{protocol=http/1.1, code=200, message=OK, url=http://xxx/}

Interceptor(拦截器)

Interceptor:监听网络的请求与变化。

实现方式:

  • 自定义类实现Interceptor接口
  • OkHttpClient.Builder().addInterceptor(自定义Interceptor).build();

作用:

  • 打印网络请求的请求和响应的信息。
  • 对网络请求做统一处理,列入添加共同的头信息。

打印网络请求的信息

为了方便,使用Eclipse进行编写。

static class LoggingInterceptor implements Interceptor {public Response intercept(Chain chain) throws IOException {// 固定写法Request request = chain.request();// 固定写法Response response = chain.proceed(request);// --------Log 信息---在android 中改成Log.i()即可System.out.println("=====请求========");// 请求行System.out.println(request);// 请求头信息System.out.println(request.headers());// form 表单信息。注意,此时只对form 表单适用FormBody form = (FormBody) request.body();for (int i = 0; i < form.size(); i++) {System.out.println(form.encodedName(i) + "="+ form.encodedValue(i));}System.out.println("=====响应========");// 响应行System.out.println(response);// 响应头System.out.println(response.headers());// 响应体System.out.println(response.body().string());return response;}}

添加Interceptor

        final OkHttpClient client = new OkHttpClient.Builder()// 添加Interceptor.addNetworkInterceptor(new LoggingInterceptor()).build();Request request = new Request.Builder().url(BAIDU_MP3_PATH).post(new FormBody.Builder().add("name", "123").build()).build();....

注意,使用的POST 表单提交。

看一下结果

=====请求========
Request{method=POST, url=http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=1&offset=0&size=1, tag=Request{method=POST, url=http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=1&offset=0&size=1, tag=null}}
Content-Type: application/x-www-form-urlencoded
Content-Length: 8
Host: tingapi.ting.baidu.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.3.1name=123
=====响应========
Response{protocol=http/1.1, code=200, message=OK, url=http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&type=1&offset=0&size=1}
Date: Wed, 29 Jun 2016 08:22:28 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
X-LIGHTTPD-LOGID: 624562847
RT: 624562847_d41d8cd98f00b204e9800998ecf8427e_d41d8cd98f00b204e9800998ecf8427e
Server: Apache1.0
SC: MISS.0.0
tracecode: 13487736192701306048062916
Set-Cookie: BAIDUID=8184D1B9CC4C45EB85C3AB62E8441688:FG=1; expires=Thu, 29-Jun-17 08:22:28 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1
P3P: CP=" OTI DSP COR IVA OUR IND COM "{"song_list":[{"artist_id":"247010469","language":"\u56fd\u8bed","pic_big":"http:\/\/musicdata.baidu.com\/data2\/pic\/0c87cb20fd6b543cd1c90d1d82f1f6c5\/266782982\/266782982.jpg","pic_small":"http:\/\/musicdata.baidu.com\/data2\/pic\/169cbb0d82522568dea198363f7028ec\/266782985\/266782985.jpg","country":"\u5185\u5730","area":"0","publishtime":"2016-06-20","album_no":"1","lrclink":"http:\/\/musicdata.baidu.com\/data2\/lrc\/1f75306d7f1e25f723d3d175f5ef3d46\/266791084\/266791084.lrc","copy_type":"1","hot":"276927","all_artist_ting_uid":"232954914","resource_type":"0","is_new":"1","rank_change":"0","rank":"1","all_artist_id":"247010469","style":"\u6d41\u884c","del_status":"0","relate_status":"0","toneid":"0","all_rate":"64,128,256","sound_effect":"0","file_duration":0,"has_mv_mobile":1,"versions":"","bitrate_fee":"{\"0\":\"0|0\",\"1\":\"-1|-1\"}","song_id":"266784254","title":"\u7ea2","ting_uid":"232954914","author":"\u51af\u5efa\u5b87","album_id":"266784256","album_title":"\u7ea2","is_first_publish":0,"havehigh":0,"charge":0,"has_mv":1,"learn":0,"song_source":"web","piao_id":"0","korean_bb_song":"1","resource_type_ext":"1","mv_provider":"0100000000","artist_name":"\u51af\u5efa\u5b87"}],"billboard":{"billboard_type":"1","billboard_no":"1871","update_date":"2016-06-28","billboard_songnum":"190","havemore":1,"name":"\u65b0\u6b4c\u699c","comment":"\u8be5\u699c\u5355\u662f\u6839\u636e\u767e\u5ea6\u97f3\u4e50\u5e73\u53f0\u6b4c\u66f2\u6bcf\u65e5\u64ad\u653e\u91cf\u81ea\u52a8\u751f\u6210\u7684\u6570\u636e\u699c\u5355\uff0c\u7edf\u8ba1\u8303\u56f4\u4e3a\u8fd1\u671f\u53d1\u884c\u7684\u6b4c\u66f2\uff0c\u6bcf\u65e5\u66f4\u65b0\u4e00\u6b21","pic_s640":"http:\/\/c.hiphotos.baidu.com\/ting\/pic\/item\/f7246b600c33874495c4d089530fd9f9d62aa0c6.jpg","pic_s444":"http:\/\/d.hiphotos.baidu.com\/ting\/pic\/item\/78310a55b319ebc4845c84eb8026cffc1e17169f.jpg","pic_s260":"http:\/\/b.hiphotos.baidu.com\/ting\/pic\/item\/e850352ac65c1038cb0f3cb0b0119313b07e894b.jpg","pic_s210":"http:\/\/business.cdn.qianqian.com\/qianqian\/pic\/bos_client_c49310115801d43d42a98fdc357f6057.jpg","web_url":"http:\/\/music.baidu.com\/top\/new"},"error_code":22000}

打印成功。。。。

当然,该实现比较粗糙,仅作原理的解释

通过上面的实现,可以看到在LoggingInterceptor中可以获取到request对象,那么我们可以通过设置其header(),实现全局的request头部信息的修改。

该博客中的源码已经共享到https://github.com/AlexSmille/alex_mahao_sample/tree/master/networklib,有需要请移步。

okhttp使用总结相关推荐

  1. 为什么要使用Retrofit封装OkHttp,而不单独使用OkHttp?

    OkHttp的优点: 开源的轻量级框架.高效.快速的请求客户端,可以单独使用它来实现网络请求. 支持SPDY: 支持连接池,可极大减少延时: 支持Gzip压缩响应体,降低传输内容的大小: 支持Http ...

  2. HTTP 2.0与OkHttp

     HTTP 2.0是对1.x的扩展而非替代,之所以是"2.0",是因为它改变了客户端与服务器之间交换数据的方式.HTTP 2.0增加了新的二进制分帧数据层,而这一层并不兼容之前的H ...

  3. 彻底理解OkHttp - OkHttp 源码解析及OkHttp的设计思想

    OkHttp 现在统治了Android的网络请求领域,最常用的框架是:Retrofit+okhttp.OkHttp的实现原理和设计思想是必须要了解的,读懂和理解流行的框架也是程序员进阶的必经之路,代码 ...

  4. 再见,HttpClient!再见,Okhttp!

    点击关注公众号,Java干货及时送达 作者:元人部落 来源:www.cnblogs.com/bryan31/p/13359376.html 1.背景 因为业务关系,要和许多不同第三方公司进行对接.这些 ...

  5. 我终于决定要放弃 okhttp、httpClient,选择了这个牛逼的神仙工具!贼爽!

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 在SpringBoot项目直接使用okhttp.httpCl ...

  6. 我终于决定要放弃 okhttp、httpClient,选择了这个牛逼的神仙工具!贼爽

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 在SpringBoot项目直接使用okhttp.httpC ...

  7. 扔掉okhttp、httpClient,来试试这款轻量级HTTP客户端神器?

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者: 伍陆七 juejin.cn/post/689848 ...

  8. HTTP客户端连接,选择HttpClient还是OkHttp?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者: 何甜甜在吗 juejin.im/post/5e156c80 ...

  9. 一行代码实现Okhttp,Retrofit,Glide下载上传进度监听

    2019独角兽企业重金招聘Python工程师标准>>> 发表上篇文章 我一行代码都不写实现Toolbar!你却还在封装BaseActivity? 已是一个月前的事情~ 上篇文章的研究 ...

  10. java accept encoding_Accept-Encoding gzip 乱码 和Okhttp的解决方法

    在使用okhttp请求服务器数据的时候,发现返回的数据一直都是乱码,但是使用fiddler抓包,decode后,可以正常显示.刚开始一直怀疑是编码的问题,后来对比了hex的数据和程序中乱码的二进制,发 ...

最新文章

  1. 数据驱动安全需三大核心新技术
  2. 14,matlab中如何查看程序中所调用的函数
  3. 嵌入式软件工程师笔试题(含答案)
  4. 局部类的引用成员函数或虚函数必须进行定义
  5. 在做研究的时候很重要的事情
  6. rabbitmq java 应用实例
  7. 在UE中自由绘制基本图元的几种方法
  8. 1123. Is It a Complete AVL Tree (30)
  9. IDEA 自动生成 serialVersionUID 的设置
  10. CSU计算机图形学复习
  11. scala下载新的版本号
  12. 整体资产评估需要资料清单
  13. windows11 微信双开的方法
  14. PMP证书可以办北京工作居住证的消息,别说你还不知道!
  15. GitLab 安全漏洞 (CVE-2016-4340)复现
  16. 硕士研究生论文查重率多少合格?
  17. 【源代码】Python制作的赛车小游戏,逆行飙车
  18. 1.1 Java基础(一)概述
  19. 基于NETAPP实现内网穿透
  20. android xposed如何写,Android Xposed 模块与宿主App 配置读写

热门文章

  1. 【渝粤题库】陕西师范大学111118 商法学 作业
  2. QT实现图片的滚轮缩放、框选放大、拖拽移动
  3. int x=3,y=2;则表达式x+=x*=y+8的值为(60)
  4. 整理一些前端模版比较好的网站
  5. 物联网专业并不好_在广阔的物联网中,“智能”仍然并不意味着安全
  6. 2016年中山市信息学竞赛暨全国信息学联赛成绩表(普及组)
  7. 股票分时数据获取-东方财富
  8. Cesium火灾动画(模型动画,粒子特效)
  9. Wireshark数据包分析——Teardrop泪滴攻击
  10. 【史上最全】如何建立模型