android Volley解析之自定义CookieObjectRequest

      以前项目中涉及到Http请求时,一直用的是开源项目asncclient,封装的非常好,使用起来也非常的方便,不再需要自己去管理线程的生命周期,只需要创建一个请求,写一个请求回调即可,13年,google推出了velloy请求框架,功能基本与asyncclient 一样,都是为了简化网络请求编程,但更加灵活,用户可以根据需求自定义不同的请求,关于 Velloy的基本用法就不在说了,网上有许多教程,今天的文章主要讲一下,如何自定义一个带Cookie的并且直接返回Object类型的Request .这一类型的请求也一定是程序 中最常用 的.

   先看一下,Velloy村身为我们提供了那些请求类型:

    1.StringRequest,专门用来处理String类型的数据请求;

     2.JsonObjectRequest和JsonArrayRequest,专门用来处理Json对象类型的数据请求

     显然,Velloy自带的这几请求类型并不是我们程序中最常用的,无论是返回JsonObject还是String,都需要我们二次处理为对象类型,那么可不可以有一个请求返回的直接就是我们需要的 Entity对象呢,当然是可以的,其次,Velloy为我们提供的请求 都是无Cookie管理的,这显然也是不 完整的.

      基于以上两点原因,我们自定义一个再Cookie管理的,直接返回Entity对象的Request.先看一下StringRequest类的源码,源码如下:   

    public class StringRequest extends Request<String> {  
        private final Listener<String> mListener;  
      
        public StringRequest(int method, String url, Listener<String> listener,  
                ErrorListener errorListener) {  
            super(method, url, errorListener);  
            mListener = listener;  
        }  
      
        public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {  
            this(Method.GET, url, listener, errorListener);  
        }  
      
        @Override  
        protected void deliverResponse(String response) {  
            mListener.onResponse(response);  
        }  
      
        @Override  
        protected Response<String> parseNetworkResponse(NetworkResponse response) {  
            String parsed;  
            try {  
                parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));  
            } catch (UnsupportedEncodingException e) {  
                parsed = new String(response.data);  
            }  
            return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));  
        }  
    }  
      源码很简单,我们需要注意的也就是parseNetworkResponse这个方法,它是处理服务器返回数据的核心方法,在StringRequest 类的处理中,就是拿到响应体的数据,再根据头中的请求编码格式,转化为一个字符串,所以我们只要在此方法中将返回 的数据转化为我们需要的对象类型既可.下面看代码:    

     

    public class ObjectRequest extends Request<Object> {  
      
            //请求成功回调  
        private final Listener<Object> mListener;  
            //实体对象字节码  
            private final Class<?> clazz;  
            //请求参数列表  
            private final HashMap<String, String> paramsMap;  
      
        public ObjectRequest(String url, HashMap<String, String> paramsMap,  
                Listener<Object> listener, ErrorListener errorListener,  
                Class<?> clazz) {  
            super(Method.POST, url, errorListener);  
            this.mListener = listener;  
            this.clazz = clazz;  
            this.paramsMap = paramsMap;  
        }  
      
        /** 
         * 添加请求头部信息 
         */  
        @Override  
        public Map<String, String> getHeaders() throws AuthFailureError {  
                    //<span style="color:#FF0000;">如果Application中已经有了Cookie信息,带Cookie请求.</span>  
            Map<String, String> map = new HashMap<String, String>();  
            if (VolleyApplication.getInstance().getCookie() != null) {  
                map.put("Cookie", VolleyApplication.getInstance().getCookie());  
            }  
            return super.getHeaders();  
        }  
      
        /** 
         * 添加请求参数方法 
         */  
        @Override  
        protected Map<String, String> getParams() throws AuthFailureError {  
            return paramsMap;  
        }  
      
        @Override  
        protected Response<Object> parseNetworkResponse(NetworkResponse response) {  
      
            for (String s : response.headers.keySet()) {  
                if (s.contains("Set-Cookie")) {  
                    /** 
                     *<span style="color:#FF0000;"> 保存到全局Cookie变量中,后续的请求直接取出使用</span> 
                     */  
                    VolleyApplication.getInstance().setCookie(  
                            response.headers.get(s));  
                    break;  
                }  
            }  
      
            try {  
                String string = new String(response.data,  
                        HttpHeaderParser.parseCharset(response.headers));  
                            /<span style="color:#FF0000;">/将返回的Json字符串直接转化为对象</span>  
                return Response.success(  
                        ResponseEntityToModule.parseJsonToModule(string, clazz),  
                        HttpHeaderParser.parseCacheHeaders(response));  
            } catch (UnsupportedEncodingException e) {  
                return Response.error(new ParseError(e));  
            } catch (Exception e) {  
                return Response.error(new ParseError(e));  
            }  
        }  
      
        @Override  
        protected void deliverResponse(Object response) {  
            mListener.onResponse(response);  
        }  
      
    }  
      
  很简单的我们就定制了一个直接返回对象并且处理了Cookie 的请求对象.下面看如何使用它去请求服务器.     

  1.Activity中代码:  

    public class MainActivity extends Activity implements Listener<Object>,  
            ErrorListener {  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
      
            RequestCenter.getInstance().userLogin("focusgbbuyer", "focus1234",  
                    this, this);  
        }  
      
        @Override  
        public void onErrorResponse(VolleyError error) {  
            // TODO Auto-generated method stub  
      
        }  
      
        @Override  
        public void onResponse(Object response) {  
            Log.e("Response", "Session:"+((User) response).sessionid + "\r\nCookie:"  
                    + VolleyApplication.getInstance().getCookie());  
        }  
      
    }  
   2.RequestCenter中是所有请求的集合: 

   

    public class RequestCenter {  
      
        private static RequestCenter instance = null;  
        private RequestQueue mQueue;  
        private VolleyApplication application;  
      
        private RequestCenter() {  
            application = VolleyApplication.getInstance();  
            mQueue = application.getRequestQueue();  
        }  
      
        public static RequestCenter getInstance() {  
      
            if (instance == null) {  
      
                synchronized (RequestCenter.class) {  
                    if (instance == null) {  
                        instance = new RequestCenter();  
                    }  
                }  
            }  
            return instance;  
        }  
      
        /** 
         * 用户登录请求 
         *  
         * @param username 
         *            用户名 
         * @param password 
         *            密码 
         * @param context 
         * @param lisener 
         *            登录结果回调 
         */  
        public void userLogin(String username, String password,  
                Listener<Object> listener, ErrorListener errorListener) {  
            HashMap<String, String> params = new HashMap<String, String>();  
            params.put("loginId", username);  
            params.put("password", password);  
            params.put("region", "MIC for Buyer Android");  
      
            ObjectRequest stringRequest = new ObjectRequest(  
                    UrlConstants.USER_LOGIN, params, listener, errorListener,  
                    User.class);  
            mQueue.add(stringRequest);  
        }  
    }  

           使用单例确保这些大对象,只有一个实例既可.经过这样一封装,使用起来很简单了.下面看服务器的返回数据.


        

           好了,完全符合我们的要求,有新需求还可以在上面直接修改,下面是Demp源码:

           VolleyDemo源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值