在OkHttp3中,对cookie而言,新增了两个类Cookiejar
、Cookie
两个类,在了解这两个类之前,先去看一下HttpEngine
关于cookie管理的变化
OkHttp默认是不保存Cookie的,如果我们需要OkHttp管理Cookie的话,需要给OkHttpClient设置CookieJar对象。
final OkHttpClient client = new OkHttpClient().newBuilder() .followRedirects(false) //禁制OkHttp的重定向操作,我们自己处理重定向 .followSslRedirects(false) .cookieJar(new LocalCookieJar()) //为OkHttp设置自动携带Cookie的功能 .build(); //CookieJar是用于保存Cookie的 class LocalCookieJar implements CookieJar{ List<Cookie> cookies; @Override public List<Cookie> loadForRequest(HttpUrl arg0) { if (cookies != null) return cookies; return new ArrayList<Cookie>(); } @Override public void saveFromResponse(HttpUrl arg0, List<Cookie> cookies) { this.cookies = cookies; } }
为了更加自由定制化的cookie管理。其中loadForRequest()
、saveFromResponse()
这两个方法最为关键,分别是在发送时向request header中加入cookie,在接收时,读取response header中的cookie。
现在去看Cookiejar
这个类,就很好理解了
public interface CookieJar { /** A cookie jar that never accepts any cookies. */ CookieJar NO_COOKIES = new CookieJar() { @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { } @Override public List<Cookie> loadForRequest(HttpUrl url) { return Collections.emptyList(); } }; /** * Saves {@code cookies} from an HTTP response to this store according to this jar's policy. * * <p>Note that this method may be called a second time for a single HTTP response if the response * includes a trailer. For this obscure HTTP feature, {@code cookies} contains only the trailer's * cookies. */ void saveFromResponse(HttpUrl url, List<Cookie> cookies); /** * Load cookies from the jar for an HTTP request to {@code url}. This method returns a possibly * empty list of cookies for the network request. * * <p>Simple implementations will return the accepted cookies that have not yet expired and that * {@linkplain Cookie#matches match} {@code url}. */ List<Cookie> loadForRequest(HttpUrl url); }
so! 在OkHttpClient创建时,传入这个CookieJar的实现,就能完成对Cookie的自动管理了
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>(); OkHttpClient okHttpClient = new OkHttpClient.Builder() .cookieJar(new CookieJar() { @Override public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) { cookieStore.put(httpUrl.host(), list); } @Override public List<Cookie> loadForRequest(HttpUrl httpUrl) { List<Cookie> cookies = cookieStore.get(httpUrl.host()); return cookies != null ? cookies : new ArrayList<>(); } }) .build();
这样以后发送Request都不用管Cookie这个参数也不用去response获取新Cookie什么的了。还能通过cookieStore获取当前保存的Cookie。