Android模拟浏览器维持Session

我们都知道,HTTP协议是无状态的,一旦数据交换完毕,连接就关闭,客户端和服务端互不相关,那么浏览器是怎么做到维持登录状态的呢还有保持用户数据的呢?答案是利用Cookie和Session。
我们来看看这张图。


Android模拟浏览器维持Session_第1张图片
image.png

此图是我第一次打开http://www.iconfont.cn/的返回头。画出红框的的是第一次请求 Servelet 或者 Jsp 等服务端程序返回的。
然后我刷新该页面,返回头变成了下图所示

Android模拟浏览器维持Session_第2张图片
image.png

留意到Set-Cookie只变成了一个了吗。这是后台的处理。
另外一个其实加入到了请求头的Cookie中,这是浏览器的默认行为,用于维持服务端的Session对象
在此后面的请求,浏览器则会将其加入请求头的Cookie中,其中保存着一些用户的数据。
显然,在安卓端我们也可以模仿这种做法(当然,前提是后台的确有利用Cookie和Session存储数据)

下面我以Retrofit为例编写代码

//Interceptor即拦截器,可用于修改请求前的请求体,以及请求后的返回体
public class CookieInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {

    String cookie;
    Request request;
    Response response;
    //cookieMgr是封装的一个SharePreference类。 这里不用太在意
    CookieMgr cookieMgr = new CookieMgr("cookie")

    //获取存储在本地的cookie
    if(!(cookie = cookieMgr.get("Set-Cookie","")).equals("")){
        Request.Builder builder = chain.request().newBuilder();

    //将cookie加入请求头中
        builder.addHeader("Cookie",cookie);
        request = builder.build();
        Log.e("CookieInterceptor",cookie);
    }else{
        request = chain.request();
    }

    response = chain.proceed(request);
    //如果是第一次请求,则会在返回头得到Set-Cookie。获取并存储在本地
    if(response.header("Set-Cookie") != null){
        cookieMgr .clear("Set-Cookie");
        cookieMgr .save("Set-Cookie",response.header("Set-Cookie"));
    }

    return response;
}

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(8, TimeUnit.SECONDS)
            //构建okhttpClient加入自定义的拦截器,实现每次请求都加入Cookie
            .addInterceptor(new CookieInterceptor())
            .build();

    client = new Retrofit.Builder().client(okHttpClient).baseUrl(Constant.IP)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build().create(Api.class);

到此,每次用Retrofit请求数据,都会带上Cookie,服务端的Session就得以维持。
后台就可以利用维持的Session或Cookie存储数据,实现需求,比如维持登录状态,带验证码的登录,等等

你可能感兴趣的:(Android模拟浏览器维持Session)