在Android上进行网络请求时,经常需要维持登录之后的session和cookie状态。session和cookie是加在HTTP请求的header里的。可以通过从header中获取,进行请求时手动添加登录获取的cookie。

OkHttp提供的拦截器可以添加,删除或替换请求标头。 还可以转换具有一个请求的正文。例如,如果您连接到的Web服务器支持压缩,就可以使用应用程序拦截器添加请求体压缩。

OkHttp Interceptor

square的一张图

OkHttp提供了一个拦截器接口Interceptor和两种添加拦截器的方式:

  • Application Interceptor
  • NetWork Interceptor

两者最大的区别就是在一次网络访问中拦截的次数和拦截到的信息。

Interceptors 调用时序图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@startuml

participant client.interceptors #SpringGreen
participant RetryAndFollowUpInterceptor
participant BridgeInterceptor
participant CacheInterceptor
participant ConnectInterceptor
participant client.networkInterceptors #SpringGreen
participant CallServerInterceptor

client.interceptors -> RetryAndFollowUpInterceptor
activate client.interceptors
activate RetryAndFollowUpInterceptor

RetryAndFollowUpInterceptor -> BridgeInterceptor
activate BridgeInterceptor

BridgeInterceptor -> CacheInterceptor
activate CacheInterceptor

CacheInterceptor -> ConnectInterceptor
activate ConnectInterceptor

ConnectInterceptor -> client.networkInterceptors
activate client.networkInterceptors

client.networkInterceptors -> CallServerInterceptor
activate CallServerInterceptor

CallServerInterceptor --> client.networkInterceptors
deactivate CallServerInterceptor

client.networkInterceptors --> ConnectInterceptor
deactivate client.networkInterceptors

ConnectInterceptor --> CacheInterceptor
deactivate ConnectInterceptor

CacheInterceptor --> BridgeInterceptor
deactivate CacheInterceptor

BridgeInterceptor --> RetryAndFollowUpInterceptor
deactivate BridgeInterceptor

RetryAndFollowUpInterceptor --> client.interceptors
deactivate RetryAndFollowUpInterceptor
deactivate client.interceptors

@enduml

Application Interceptor

  • 不必担心中间响应,如重定向和重试。
  • 总是调用一次,即使是从缓存中提供的HTTP响应。
  • 遵守应用程序的原始意图。OkHttp注入的标题,如If-None-Match,不会生效。
  • 允许短路,不调用Chain.proceed()。
  • 允许重试并多次调用Chain.proceed()。

NetWork Interceptor

  • 能够对重定向和重试等中间响应进行操作。
  • 对于缓存网络短路的响应不被调用。
  • 观察数据,就像通过网络传输一样。
  • 访问携带请求的连接。

使用拦截器自动储存和添加cookie

OkHttp 有提供 CookieJar 辅助存储 cookie

OkHttp提供了Interceptors拦截器可以很方便的实现类似cookie本地化维持的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private class AddCookiesInterceptor implements Interceptor {

@Override
public Response intercept(@NonNull Chain chain) throws IOException {
//get cached cookie from local
HashSet<String> cookies = (HashSet<String>) SharedPrefsUtils
.getStringSetPreference(
AccessApplication.getGlobalContext(),
C.SP_COOKIE);
//add cached cookie into request
Request.Builder builder = chain.request().newBuilder();
if (cookies != null) {
for (String cookie : cookies) {
builder.addHeader("Cookie", cookie);
}
}
Request request = builder.build();
//get response
Response response = chain.proceed(request);
//save response cookie to local cache
List<String> newCookies = response.headers("Set-Cookie");
if (!newCookies.isEmpty()) {
HashSet<String> cookie = new HashSet<>();
for (String header : newCookies) {
cookie.add(header);
}
SharedPrefsUtils.setStringSetPreference(
AccessApplication.getGlobalContext(),
C.SP_COOKIE, cookie);
}
return response;
}
}


Android     

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!