Android中如何保存cookie

android中有时候需要保存由服务器返回的cookie,那么如何存取呐?
这需要我们自定义两个拦截器来实现
SaveCookiesInterceptor和AddCookiesInterceptor
首先定义响应拦截器,该拦截器实现从response获取set-cookie字段的值,并将其保存在本地。

代码如下:

public class SaveCookiesInterceptor implements Interceptor {
    private static final String COOKIE_PREF = "cookies_prefs";
    private Context mContext;

    public SaveCookiesInterceptor(Context context) {
        mContext = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        //set-cookie可能为多个
        if (!response.headers("set-cookie").isEmpty()) {
            List cookies = response.headers("set-cookie");
            String cookie = encodeCookie(cookies);
            saveCookie(request.url().toString(),"gfan.com",cookie);
        }

        return response;
    }

    //整合cookie为唯一字符串
    private String encodeCookie(List cookies) {
        StringBuilder sb = new StringBuilder();
        Set set=new HashSet<>();
        for (String cookie : cookies) {
            String[] arr = cookie.split(";");
            for (String s : arr) {
                if(set.contains(s))continue;
                set.add(s);

            }
        }

        Iterator ite = set.iterator();
        while (ite.hasNext()) {
            String cookie = ite.next();
            sb.append(cookie).append(";");
        }

        int last = sb.lastIndexOf(";");
        if (sb.length() - 1 == last) {
            sb.deleteCharAt(last);
        }

        return sb.toString();
    }

    //保存cookie到本地,这里我们分别为该url和host设置相同的cookie,其中host可选
    //这样能使得该cookie的应用范围更广
    private void saveCookie(String url,String domain,String cookies) {
        SharedPreferences sp = mContext.getSharedPreferences(COOKIE_PREF, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        if(url.contains("index.php?m=member&c=gfan_index&a=login")){
            if (!TextUtils.isEmpty(domain)) {
                editor.putString(domain, cookies);
            }
            editor.apply();
        }
    }
}

其次定义请求拦截器,如果该请求存在cookie,则为其添加到Header的Cookie中,代码如下:

代码如下:

    public class AddCookiesInterceptor implements Interceptor {
    private static final String COOKIE_PREF = "cookies_prefs";
    private Context mContext;
    public AddCookiesInterceptor(Context context) {
        mContext = context;
    }
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request.Builder builder = request.newBuilder();
        String cookie = getCookie("", "gfan.com");
        if (!TextUtils.isEmpty(cookie)) {
            builder.removeHeader("cookie");
            builder.addHeader("cookie", cookie);
        }
        return chain.proceed(builder.build());
    }
    private String getCookie(String url, String domain) {
        SharedPreferences sp = mContext.getSharedPreferences(COOKIE_PREF, Context.MODE_PRIVATE);
        if (!TextUtils.isEmpty(domain)&&sp.contains(domain) && !TextUtils.isEmpty(sp.getString(domain, ""))) {
            return sp.getString(domain, "");
        }
        return null;
    }
}

最后在设置一下这两个拦截器即可

代码如下:

OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(TIME_OUT, TimeUnit.SECONDS);
        builder.addInterceptor(new AddCookiesInterceptor(MYApplication.appContext));
        builder.addInterceptor(new SaveCookiesInterceptor(MYApplication.appContext));
     ```   
参考文章:
[急速开发系列——Retrofit实现持久化Cookie的三种方案](http://www.2cto.com/kf/201609/548735.html)

你可能感兴趣的:(Android中如何保存cookie)