前言
Retrofit 是一款强大的网络访问框架,内置的和Okhttp结合在一起,在我们使用 Retrofit 进行网络访问的时候如何储存登录后的Cookie
设置Okhttp
//该url是登录的Url,作为cookieStore的一个key存储登录成功后的cookies
final HttpUrl httuUrl = HttpUrl.parse("http://192.168.125.118:8080/manage/user/login.do");
final OkHttpClient httpClient = new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<HttpUrl, List<Cookie>>();
//网路访问访问后将服务器返回的cookies和对应的url存储在cookieStore中
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url, cookies);
}
//网路访问开始的时候,根据当前要访问的url去查找cookie,然后将cokies放到请求头里面
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(httuUrl);
return cookies != null ? cookies : new ArrayList<Cookie>();
}
}).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.125.118:8080/manage/")
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
很明显的一点是,当我们登录成功后,第一次访问任何页面的时候, loadForRequest() 方法返回的结果都是 null ,因为在 cookieStore 中只存储了登录url以及对应的 cookies,
对应的 sessionId 是存储在登录成功返回的cookie中的,这里的调整就是将 loginUrl 作为一个固定,每次使用Retrofit访问接口的时候 loadForReques 方法就是读取登录成功返回的cookies。
如果对某些特定的接口我们需要一些特殊的cookie我们可以通过以下方法处理
处理特殊接口的cookie
//通过HttpUrl从cookieStore中获取相关cookies
StringBuilder cookieStr = new StringBuilder();
List<Cookie> cookies = httpClient.cookieJar().loadForRequest(loginRequest.url());
//处理相关cookie并拼接,也可以在cookies中增加一个等等
TODO:.......
//然后保存,就存储在了cookieJar中
httpClient.cookieJar().saveFromResponse(loginUrl,cookies);
服务代码
public interface API {
@POST("product/detail.do")
@FormUrlEncoded
Call<ResponseBody> getDetails(@Field("productId") Integer productId);
@POST("user/login.do")
@FormUrlEncoded
Call<ResponseBody> login(@Field("username") String username,@Field("password") String password);
}
登录代码
API api = retrofit.create(API.class);
final Call<ResponseBody> login = api.login("admin", "admin");
List<Cookie> loginCookies;
try {
Response<ResponseBody> loginResponse = login.execute();
String loginResult = loginResponse.body().string();
Log.d(TAG,loginResult);
} catch (IOException e) {
e.printStackTrace();
}
访问其他接口代码
Call<ResponseBody> detail = api.getDetails(29);
try {
//访问这个接口的时候,Retrofit中的okhttp自动回为这个request添加上cookie,通过loadForRequest方法
Response<ResponseBody> detailResponse = detail.execute();
String deatilResult = detailResponse.body().string();
Log.d(TAG,deatilResult);
} catch (IOException e) {
e.printStackTrace();
}
在api服务中的设置动态请求头
public interface API{
@POST
@FormUrlEncode
Call<Response> getDetail(@Header("Cookie") String contentRange,@Filed("name") String name);
}