项目中使用OKHttp框架作为网络库时,往往会遇到这样的情况。服务器要求客户端请求接口时要带有Cookie。OkHttp也是支持获取保存使用Cookie的。下面介绍几种常用的方法。
一.自行获取保存使用Cookie
<1> 什么时候获取
在每一次Get或者Post请求成功的onResponse方法中获取保存。
<2> 什么时候使用
在每一次Get或者Post请求创建Request 时.addHeader("cookie",cookie)。
<3> 代码实现
工具类
package com.wjn.viewlistdemo.okhttp.utils;
import android.text.TextUtils;
import com.wjn.viewlistdemo.activity.MyApplication;
import com.wjn.viewlistdemo.okhttp.constants.ROConstants;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import rx.Observable;
import rx.Subscriber;
public class RxAndroidOkhttp {
private OkHttpClient mOkHttpClient = null;//OkHttpClient 对象
private static RxAndroidOkhttp mRxAndroidOkhttp = null;//RxAndroidOkhttp 对象
/**
* 构造方法私有化
*/
private RxAndroidOkhttp() {
//创建okhttp对象 以及连接,读,取超时时间
mOkHttpClient = new OkHttpClient.Builder()
.connectTimeout(ROConstants.nettimeout, TimeUnit.SECONDS)//连接时间
.readTimeout(ROConstants.nettimeout, TimeUnit.SECONDS)//读时间
.writeTimeout(ROConstants.nettimeout, TimeUnit.SECONDS)//写时间
.retryOnConnectionFailure(true)//连接失败后是否重新连接
.build();
}
/**
* 获取此单例类对象的方法
*/
public static RxAndroidOkhttp getInstance() {
if (null == mRxAndroidOkhttp) {//单例对象为空
synchronized (RxAndroidOkhttp.class) {
mRxAndroidOkhttp = new RxAndroidOkhttp();
}
}
return mRxAndroidOkhttp;
}
/**
* get请求方法
*/
public Observable<String> get(final String url) {
//创建被观察者
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
final Subscriber mSubscriber = subscriber;
if (!mSubscriber.isUnsubscribed()) {//没有取消订阅
Request request = null;
String cookie = MyApplication.getOkhttpCookie();
if (!TextUtils.isEmpty(cookie)) {
request = new Request.Builder()
.addHeader("cookie", cookie)
.url(url)
.get()
.build();
} else {
request = new Request.Builder()
.url(url)
.get()
.build();
}
if (null != mOkHttpClient) {
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//通知订阅者的错误信息
mSubscriber.onError(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (null != response) {//response 不为空
if (response.isSuccessful()) {//response 请求成功
Headers headers = response.headers();
List<String> cookies = headers.values("Set-Cookie");
if (cookies.size() > 0) {
String session = cookies.get(0);
if (!TextUtils.isEmpty(session)) {
int size = session.length();
int i = session.indexOf(";");
if (i < size && i >= 0) {
String result = session.substring(0, i);
MyApplication.setOkhttpCookie(result);
}
}
}
//通知订阅者的成功信息
mSubscriber.onNext(response.body().string());
} else {//response 请求失败
//通知订阅者的错误信息
IOException IOExceptionx = new IOException();
mSubscriber.onError(IOExceptionx);
}
} else {//response 为空
//通知订阅者的错误信息
IOException IOExceptionx = new IOException();
mSubscriber.onError(IOExceptionx);
}
//通知完毕
mSubscriber.onCompleted();
}
});
}
}
}
});
return observable;
}
}
Application
package com.wjn.viewlistdemo.activity;
import android.app.Application;
public class MyApplication extends Application {
private static String okhttpCookie;
@Override
public void onCreate() {
super.onCreate();
}
public static String getOkhttpCookie() {
return okhttpCookie;
}
public static void setOkhttpCookie(String okhttpCookie) {
MyApplication.okhttpCookie = okhttpCookie;
}
}
二.使用OkHttp框架的CookieJar自动管理使用Cookie
代码实现
Cookie管理类
package com.wjn.viewlistdemo.okhttp.cookie;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
/**
* OkHttp框架Cookie管理类
*/
public class CookieJarManager implements CookieJar {
private final String TAG = "CookieJarManager";
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
if (null == url || null == cookies || cookies.size() <= 0) {
return;
}
cookieStore.put(url.host(), cookies);
for (Cookie cookie : cookies) {
Log.d(TAG, "cookie Name:" + cookie.name());
Log.d(TAG, "cookie Path:" + cookie.path());
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
if (null != url) {
List<Cookie> cookies = cookieStore.get(url.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
} else {
return new ArrayList<Cookie>();
}
}
}
OkHttp设置Cookie
mOkHttpClient = new OkHttpClient.Builder()
.connectTimeout(ROConstants.nettimeout, TimeUnit.SECONDS)//连接时间
.readTimeout(ROConstants.nettimeout, TimeUnit.SECONDS)//读时间
.writeTimeout(ROConstants.nettimeout, TimeUnit.SECONDS)//写时间
.retryOnConnectionFailure(true)//连接失败后是否重新连接
.cookieJar(new CookieJarManager())//自动管理Cookie
.build();
三.使用OkHttp框架的拦截器(Interceptor)管理使用Cookie
详解:https://blog.csdn.net/weixin_37730482/article/details/72834344