Retrofit2.0中,每个请求之间是独立开的,这产生一个问题,也就是如何保持Session信息,更通俗易懂的说,就是如何保持登录状态,如果不做任何操作,那么不管登录多少次,都是无效的,无法进行其他权限操作。这里要提交到浏览器,浏览器是默认自动保存服务器发送过来的Session信息的,也就是默认保持Session信息的,只有当浏览器关闭,才会清除这些Session信息。
说到这里,你可能会说Session不是保存在服务器的吗?注意,这里用的是“保持”,换一种说法,就是让服务器知道这还是你,而不是新的用户连接。
Session 机制:
一般来说,服务器使用Session来判断用户是否登录,也就是:
当服务器与客户建立新的连接时,会创建一个会话Session,每个用户的Session的id都是不一样的,这是识别每个客户的一个id,当创建客户的Session后会放在响应体Response的头部信息中,具体位置为:
也就是Cookie的第一个字符到第一个;之间,注意,这是一个key-value,我们只需要在登录后返回的Response的头部将这一串信息拿下,并在以后每一次请求中,在Cookie加入这一串Session信息,即可实现Session保持,或者说 保持登录状态。
1.导包
导入拦截器,主要作用是:1.拦截每一次请求。2.在拦截的请求中的Cookie中加入Session信息。
compile 'com.squareup.okhttp3:logging-interceptor:3.8.1'
2.在第一次请求的响应体中,从Cookie中拿出Session信息。如下:
主要代码:
public class UserController {
public static UserService userService= RetrofitFactory.createRetrofit().create(UserService.class);
public static void login(String username, String password, final NetCallback callback) {
Map map=new HashMap<>();
map.put("userId",username);
map.put("password",password);
Call call=userService.login(map);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
if(response.isSuccessful()){
try {
HeaderInterceptor.cookie=response.headers().get("set-cookie");
Log.e("NetWork=>headers", HeaderInterceptor.cookie);
callback.onSuccess(new Gson().fromJson(response.body().string(), ValidateResult.class));
} catch (IOException e) {
callback.onError(10001);
}
}
else{
Log.e("NetWork",response.message());
}
}
@Override
public void onFailure(Call call, Throwable t) {
Log.e("NetWork",t.getLocalizedMessage());
callback.onError(10002);
}
});
}
}
其中:获取如下:
public void onResponse(Call call, Response response) {
if(response.isSuccessful()){
try {
HeaderInterceptor.cookie=response.headers().get("set-cookie");
Log.e("NetWork=>headers", HeaderInterceptor.cookie);
callback.onSuccess(new Gson().fromJson(response.body().string(), ValidateResult.class));
} catch (IOException e) {
callback.onError(10001);
}
}
else{
Log.e("NetWork",response.message());
}
}
使用 response.headers().get('set-cookie");获取cookie信息,并将其保存下来,这里保存在自定义拦截器HeaderInterceptor里面.
3.创建拦截器HeaderInterceptor
代码如下:
public class HeaderInterceptor implements Interceptor {
//保存cookie
public static String cookie=null;
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
if(cookie!=null) {
builder.addHeader("Cookie", cookie);
if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {
builder.addHeader("Connection", "close");
}
}
else{
Log.e("Cookie","Cookie not found");
}
return chain.proceed(builder.build());
}
}
4.测试。