Retrofit2.0+Gson+RxJava 框架 之 Session保持(解决Session无效问题) 【Android】

       Retrofit2.0中,每个请求之间是独立开的,这产生一个问题,也就是如何保持Session信息,更通俗易懂的说,就是如何保持登录状态,如果不做任何操作,那么不管登录多少次,都是无效的,无法进行其他权限操作。这里要提交到浏览器,浏览器是默认自动保存服务器发送过来的Session信息的,也就是默认保持Session信息的,只有当浏览器关闭,才会清除这些Session信息。

     说到这里,你可能会说Session不是保存在服务器的吗?注意,这里用的是“保持”,换一种说法,就是让服务器知道这还是你,而不是新的用户连接。

Session 机制:

     一般来说,服务器使用Session来判断用户是否登录,也就是:

Retrofit2.0+Gson+RxJava 框架 之 Session保持(解决Session无效问题) 【Android】_第1张图片

       当服务器与客户建立新的连接时,会创建一个会话Session,每个用户的Session的id都是不一样的,这是识别每个客户的一个id,当创建客户的Session后会放在响应体Response的头部信息中,具体位置为:

Retrofit2.0+Gson+RxJava 框架 之 Session保持(解决Session无效问题) 【Android】_第2张图片

也就是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.测试。

(完)

 

你可能感兴趣的:(Android)