您的位置:首页 > 移动开发 > Android开发

【Android】volley 之 session id 问题解决

2016-01-25 23:09 441 查看
最近跟着老师的工作室做项目,受益颇丰。

一方面,按照项目需求来实现些东西比自己造轮子得到的锻炼要有效的多,另一方面,遇到问题自己也有压迫感积极的去解决问题。

今天先记录一下 自己碰到的一个问题 网络访问用户状态的存储。

(后台服务器端了解的不多,可能叙述有误)若每次访问都带上用户id和password,那就不会有后台的用户判断问题。若用户一次登录之后,之后的请求不带参数,则返回的数据为空,获取不到需要的信息。而浏览器不会出现这个问题是因为在你使用浏览器登陆后,浏览器会自动存下后台返回的session的id,之后的每次请求浏览器会自动将存下来的session的id放在header里,这样后台就知道是哪个用户在访问。然而Android里没有这个机制,不会像浏览器那样,所以就需要我们自己完成以上的操作。

明白的大致的问题,就需要借鉴前辈的经验了。网上google出很多种解决办法,现在只记录几种,之后会继续更新完善。

————————————————————————————————————————————————————————————————————————

1.第一种解决方法的思路和上面描述的一致,存session的id,然后请求时就加到header里。

这是登陆时存储session 的 id,说明见代码注释。

/*
       获取登陆成功之后的session id并且存储到全局变量 localCookie
       测试用,应在登陆界面实现
     */
    private void getVolleyMa() {
        RequestQueue requestQueue = Volley.newRequestQueue(getContext());
        String JSONDataUrl = "http://222.194.15.118:9090/Ecommunity/loginByUserPhone?userPhone=13912345678&userPsw=123456";
        //POST方式更加安全
        StringRequest stringrequest = new StringRequest(Request.Method.POST, JSONDataUrl,
                new Response.Listener<String>() {

                    @Override
                    public void onResponse(String response) {
                        // TODO Auto-generated method stub
                        
                        Log.e("TAG", response);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError arg0) {
                // TODO Auto-generated method stub
            }
        }) {
            //重写parseNetworkResponse方法,返回的数据中 Set-Cookie:***************;
            //其中**************为session id
            @Override
            protected Response<String> parseNetworkResponse(
                    NetworkResponse response) {
                Response<String> superResponse = super
                        .parseNetworkResponse(response);
                Map<String, String> responseHeaders = response.headers;
                String rawCookies = responseHeaders.get("Set-Cookie");
                //Constant是一个自建的类,存储常用的全局变量
                Constant.localCookie = rawCookies.substring(0, rawCookies.indexOf(";"));
                Log.d("sessionid", "sessionid----------------" + Constant.localCookie);
                return superResponse;
            }
        };
        requestQueue.add(stringrequest);
    }
这只是一个简单的StringRequest,主要是通过登陆这个操作获得后台分配的session的id。

全局变量localCookie定义:public static volatile String localCookie = null; 接下就是在请求时重写getHeader()方法。

private void getVolley(final String isUrl) {
        RequestQueue requestQueue = Volley.newRequestQueue(getContext());
        String JSONDataUrl = isUrl;
        JsonObjectRequest objectRequest = new JsonObjectRequest(JSONDataUrl,null,
                new Response.Listener<JSONObject>(){
                    @Override
                    public void onResponse(JSONObject jsonObject) {
                        //取到的jsonObject数据在这里处理操作
                   
                    }
                },new Response.ErrorListener(){

            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Log.e("TAGArray", volleyError.getMessage(), volleyError);
            }
        }){
            //重写getHeaders 默认的key为cookie,value则为localCookie
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                if (Constant.localCookie != null && Constant.localCookie.length() > 0) {
                        HashMap<String, String> headers = new HashMap<String, String>();
                        headers.put("cookie", Constant.localCookie);
                        Log.d("调试", "headers----------------" + headers);
                        return headers;
                    }else {
                        return super.getHeaders();
                }
            }
        };

        requestQueue.add(objectRequest);

    }
至此,完整的解决问题的思路已经全部实现。(小插曲)这两个方法开始被我写到一个类里,出现的问题还是有时候数据为空。这是因为网络操作都会自己开一个线程,所以可能存session的id的那一步还没有执行,请求的操作先执行了的情况,那么session id为空,当然访问的数据也为空了。可以按先后顺序,让后一个进程sleep一个时间保证在存了session id 之后,或者是使用handler,或者是在之前的页面完成存id操作
都可以。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: