Retrofit--记使用Retrofit时遇到的一个坑

绪论

很久没有写博客了,上次是写了使用Retrofit时怎么设置OKHttp,如果你没看到请看:
Retrofit–使用Retrofit时怎样去设置OKHttp
你也可以看看我是怎样使用Retrofit的:
Retrofit–合理封装回调能让你的项目高逼格
好了,今天说一下我遇到的一个坑吧。

Retrofit Cookie问题

上次我们说过怎么去实现持久化登录,本地保存用户的cookie:
1.
这里写图片描述
2.
本地新建PersistentCookieStore文件保存SP中
3.添加依赖

1
2
3
4
5
6
7
compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okio:okio:1.6.0'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.0.0-RC1'

之前可能没说明添加哪些依赖,导致小伙伴们都问我出现了问题,这次说明一下。

我在做项目的时候遇到的问题就是:
测试环境下:我这样保存cookie是没有问题的,而且几个小伙伴也用了这个方法到项目中也OK,但是当我们的服务器由测试切到了正式环境下之后,cookie是可以获取到的,但是服务器却怎么都不识别,这着实让我很郁闷,我不得不猜想这是后台服务器的问题,但是后台大哥一直坚持他那里面没有问题,没办法,我最后又google了一下,这种方法可以用,先说一下:

同样给HttpClient添加拦截器:
这里写图片描述
看一下ReceivedCookiesInterceptor和AddCookiesInterceptor这两个文件:

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
50
51
package com.hankkin.bpm.http.cookie;
import android.content.Context;
import android.content.SharedPreferences;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Response;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
public class ReceivedCookiesInterceptor implements Interceptor {
private Context context;
public ReceivedCookiesInterceptor(Context context) {
super();
this.context = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
if (!originalResponse.headers("Set-Cookie").isEmpty()) {
final StringBuffer cookieBuffer = new StringBuffer();
Observable.from(originalResponse.headers("Set-Cookie"))
.map(new Func1<String, String>() {
@Override
public String call(String s) {
String[] cookieArray = s.split(";");
return cookieArray[0];
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String cookie) {
cookieBuffer.append(cookie).append(";");
}
});
SharedPreferences sharedPreferences = context.getSharedPreferences("cookie", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("cookie", cookieBuffer.toString());
editor.commit();
}
return originalResponse;
}
}
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
package com.hankkin.bpm.http.cookie;
import android.content.Context;
import android.content.SharedPreferences;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import rx.Observable;
import rx.functions.Action1;
public class AddCookiesInterceptor implements Interceptor {
private Context context;
private String lang;
public AddCookiesInterceptor(Context context,String lang) {
super();
this.context = context;
this.lang = lang;
}
@Override
public Response intercept(Chain chain) throws IOException {
final Request.Builder builder = chain.request().newBuilder();
SharedPreferences sharedPreferences = context.getSharedPreferences("cookie", Context.MODE_PRIVATE);
Observable.just(sharedPreferences.getString("cookie", ""))
.subscribe(new Action1<String>() {
@Override
public void call(String cookie) {
if (cookie.contains("lang=ch")){
cookie = cookie.replace("lang=ch","lang="+lang);
}
if (cookie.contains("lang=en")){
cookie = cookie.replace("lang=en","lang="+lang);
}
//添加cookie
builder.addHeader("Cookie", cookie);
}
});
return chain.proceed(builder.build());
}
}
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
package com.hankkin.bpm.http.cookie;
import android.content.Context;
import android.content.SharedPreferences;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import rx.Observable;
import rx.functions.Action1;
public class AddCookiesInterceptor implements Interceptor {
private Context context;
private String lang;
public AddCookiesInterceptor(Context context,String lang) {
super();
this.context = context;
this.lang = lang;
}
@Override
public Response intercept(Chain chain) throws IOException {
final Request.Builder builder = chain.request().newBuilder();
SharedPreferences sharedPreferences = context.getSharedPreferences("cookie", Context.MODE_PRIVATE);
Observable.just(sharedPreferences.getString("cookie", ""))
.subscribe(new Action1<String>() {
@Override
public void call(String cookie) {
if (cookie.contains("lang=ch")){
cookie = cookie.replace("lang=ch","lang="+lang);
}
if (cookie.contains("lang=en")){
cookie = cookie.replace("lang=en","lang="+lang);
}
//添加cookie
builder.addHeader("Cookie", cookie);
}
});
return chain.proceed(builder.build());
}
}

大家可以忽略lang的东西,那些是多元化传给服务器的。
我最后的猜测也就是:服务器的正式和测试环境下他在设置cookie值的时候并没有在cookie里面设置完整,所以导致我从cookie里面取的值不正确或者不是最新的,当然这也只是我的猜测,很可能还和环境问题有关系。
总之我们又有了一种持久化管理cookie的方法,记录下来方便以后使用。
参考文章:
Retrofit使用OkHttp保存和添加cookie