封装Volley使Volley的每个请求都自动保存和发送Cookie

思路很简单,每次请求获取到服务器返回的response就解析头部获取cookie并保存,发送请求的时候就从本地读取cookie添加到头部发送给服务器

第一步,解析http response头部的cookie并保存,自定义一个Request并重写其parseNetworkResponse方法

/**
 * 解析数据,保存Cookie
 * @param response
 * @return
 */
@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
    try {
        JSONObject jsonObject;
        /*将response构造成JSONObject返回给调用者*/
        if (response.data.length != 0) {
            String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            jsonObject = new JSONObject(jsonString);
        } else {
            jsonObject = new JSONObject();
        }
        /*获取数据头*/
        mHeader = response.headers.toString();
        /*通过正则表达式提取Cookie(JSESSIONID)*/
        Pattern pattern = Pattern.compile("Set-Cookie=.*?;");
        Matcher matcher = pattern.matcher(mHeader);
        if (matcher.find()) {
            cookieFromResp = matcher.group();
            /*获取数据头中键为Set-Cookie的值即获取Cookie*/
            cookieFromResp = cookieFromResp.substring(11, cookieFromResp.length() - 1);
            DLog.v("Cookie: " + cookieFromResp);
        }
        /*将Cookie保存到本地,下次请求数据的时候再把本地保存的Cookie发送给服务器*/
        if(!TextUtils.isEmpty(cookieFromResp)){
            CookieUtils.saveSessionID(App.getContext(),cookieFromResp);
        }
        return Response.success(jsonObject,
                HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    } catch (JSONException je) {
        return Response.error(new ParseError(je));
    }
}

第二步,发送请求的时候,从本地读取Cookie,添加到http request的头部,发送给服务器,重写getHeaders()即可

/**
 * 设置header,自动发送本地保存的Cookie
 * @return
 * @throws AuthFailureError
 */
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    headerMap.put("Accept", "application/json");
    headerMap.put("Content-Type", "application/json; charset=UTF-8");
    String cookie=CookieUtils.loadSessionID(App.getContext());
    DLog.d(cookie);
    /*将本地保存的Cookie发送给服务器*/
    if(!TextUtils.isEmpty(cookie)){
        headerMap.put("Cookie", CookieUtils.loadSessionID(App.getContext()));
    }
    return headerMap;
}

经过上边两个方法的重写就已经实现了Cookie的自动保存和自动发送

经过封装的完整的Request代码如下:

public class JsonObjectRequest extends JsonRequest<JSONObject > {
    private String mHeader;
    private String cookieFromResp = "";
    Map<String, String> headerMap = new HashMap<>();

    public JsonObjectRequest(int method, String url,
                             JSONObject jsonRequest,
                             Response.Listener<JSONObject> listener,
                             Response.ErrorListener errorListener) {
        super(  method,
                url,
                (jsonRequest == null) ? null : jsonRequest.toString(),
                listener,
                errorListener);
    }

    public JsonObjectRequest(String url,
                             JSONObject jsonRequest,
                             Response.Listener<JSONObject> listener,
                             Response.ErrorListener errorListener) {
        this(  jsonRequest == null ? Request.Method.GET : Request.Method.POST,
                url,
                jsonRequest,
                listener,
                errorListener);
    }

    /**
     * 解析数据,保存Cookie
     * @param response
     * @return
     */
    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            JSONObject jsonObject;
            /*将response构造成JSONObject返回给调用者*/
            if (response.data.length != 0) {
                String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
                jsonObject = new JSONObject(jsonString);
            } else {
                jsonObject = new JSONObject();
            }
            /*获取数据头*/
            mHeader = response.headers.toString();
            /*通过正则表达式提取Cookie(JSESSIONID)*/
            Pattern pattern = Pattern.compile("Set-Cookie=.*?;");
            Matcher matcher = pattern.matcher(mHeader);
            if (matcher.find()) {
                cookieFromResp = matcher.group();
                /*获取数据头中键为Set-Cookie的值即获取Cookie*/
                cookieFromResp = cookieFromResp.substring(11, cookieFromResp.length() - 1);
                DLog.v("Cookie: " + cookieFromResp);
            }
            /*将Cookie保存到本地,下次请求数据的时候再把本地保存的Cookie发送给服务器*/
            if(!TextUtils.isEmpty(cookieFromResp)){
                CookieUtils.saveSessionID(App.getContext(),cookieFromResp);
            }
            return Response.success(jsonObject,
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    /**
     * 设置超时
     * @return
     */
    @Override
    public RetryPolicy getRetryPolicy() {
        RetryPolicy retryPolicy= new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        return retryPolicy;
    }

    /**
     * 设置header,自动发送本地保存的Cookie
     * @return
     * @throws AuthFailureError
     */
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        headerMap.put("Accept", "application/json");
        headerMap.put("Content-Type", "application/json; charset=UTF-8");
        String cookie=CookieUtils.loadSessionID(App.getContext());
        DLog.d(cookie);
        /*将本地保存的Cookie发送给服务器*/
        if(!TextUtils.isEmpty(cookie)){
            headerMap.put("Cookie", CookieUtils.loadSessionID(App.getContext()));
        }
        return headerMap;
    }
    //将Cookie加入数据头
    public void setCookie(String cookie) {
        headerMap.put("Cookie", cookie);
    }
}
时间: 2024-10-29 00:27:28

封装Volley使Volley的每个请求都自动保存和发送Cookie的相关文章

Volley,小并发网络请求的好帮手

不得不说,当不了解一件事情的时候,就会像当然的认为,其很神秘.但是当真正的接触到了这些神秘的item,就不会有这种感觉了.作为一个android开发新手的我,刚接触到了Volley这个开源的网络请求框架,就瞬间被她打动了.下面我就谈一谈我对Volley的一些理解. Volley是什么? Volley是谷歌在2013年的I/O大会上发布的一个网络请求的框架,Volley在性能方面进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载

[asp.net mvc 奇淫巧技] 06 - 也许你的项目同一个用户的请求都是同步的

一.感慨 很久前看到一篇博客中有句话大致的意思是:“asp.net 程序性能低下的主要原因是开发人员技术参差不齐”,当时看到这句话不以为然,然而时间过的越久接触的.net 开发人员越多就越认同这句话:特别最近发现非常一个成熟的项目中有些问题非常非常影响性能,最终影响的是用户体验,借此给大家分享一下关于asp.net中一个小小的点,但对项目有很大的性能提升:以前觉得自己接触的项目少小,然后接触的项目越多,越大就会越发现,同样的问题依旧存在: 二.先从最简单的asp.net mvc例子说起 1.Co

Struts2请求数据自动封装和数据类型转换

方式1:jsp表单数据填充到action中的属性: 方式2:jsp表单数据填充到action的对象的属性: 方式1: 第一步:引包,省去 第二步:配置struts2的过滤器 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmln

很急!!! java.lang.NoClassDefFoundError: com.android.volley.toolbox.Volley

============问题描述============ 日志文件如下,不知道是什么原因报如下错误 08-01 16:33:35.001: E/AndroidRuntime(31240): FATAL EXCEPTION: main 08-01 16:33:35.001: E/AndroidRuntime(31240): Process: cn.phonecms.main, PID: 31240 08-01 16:33:35.001: E/AndroidRuntime(31240): java.

对JdbcTemplate进行简易封装以使其更加易用

在上一篇博文<基于SpringJDBC的类mybatis形式SQL语句管理的思考与实现>中,我们实现了采用XML文件对SQL进行管理.在本篇博文中,我们将对SpringJDBC提供的JdbcTemplate进行简易封装,使其更加的易用,更加贴近上篇博文中对于SQL管理的设计. 我们希望在使用将要封装的这个工具进行数据库操作时有以下几个优势: 不处理数据获取异常 不关心日志记录 即可以使用我们XML文件中的SQL语句,也可以使用在业务方法中定义的SQL语句.(因为我们设计的XML文件并不能够非常

struts中的请求数据自动封装

Struts 2框架会将表单的参数以同名的方式设置给对应Action的属性中.该工作主要是由Parameters拦截器做的.而该拦截器中已经自动的实现了String到基本数据类型之间的转换工作.在struts中,默认使用拦截器 <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/> 进行请求数据自动封装,它会JSP中提交的

异常:java.lang.NoClassDefFoundError: com.android.volley.toolbox.Volley

原因:http://m.blog.csdn.net/blog/Melody8869/46908891 java.lang.NoClassDefFoundError: com.android.volley.toolbox.Volley导致这种异常有以下几种原因: 1.adt版本问题,更新adt版本 2.jar包问题,其原因也是adt引起,只需删除libs下下的无用jar(我的v4包问题,delete) 或者: 没有将需要导入的包复制到项目的libs文件夹中.

thinkphp 使每一个模板页都包括一个header文件和一个footer文件

在开发的过程中,常常遇到要使每一个模板页都包括一个header文件和一个footer文件.thinkPHP的模板布局为我们提供了一个叫全局配置方式可以解决问题. 1. 在配置文件里开启LAYOUT_ON 參数(默认不开启),而且设置布局入口文件名称LAYOUT_NAME(默觉得layout) 'LAYOUT_ON'=>true, 'LAYOUT_NAME'=>'layout', 2. 在模板文件夹下建立一个layout.html文件,文件内代码例如以下: <include file=&q

QT UI 使一个QWidget里面的元素自动填充满本QWidget

使一个QWidget里面的元素自动填充满本QWidget: 对象查看器,右键点击本QWidget,选择"布局",为此QWidget增加一个布局. 如果该QWidget只有一个对象,那么任意布局都可以(暂时自测是这样的),建议栅格布局吧. 如果该QWidget有多个对象,可以摆好所有对象,再右键点击本QWidget,为此QWidget增加一个布局: widget的布局属性在哪看: 如果是QStackedWidget,有多个页面,则需要逐个切到各个页面,右键点击QStackedWidget