最近跟着老师的工作室做项目,受益颇丰。
一方面,按照项目需求来实现些东西比自己造轮子得到的锻炼要有效的多,另一方面,遇到问题自己也有压迫感积极的去解决问题。
今天先记录一下 自己碰到的一个问题 网络访问用户状态的存储。
(后台服务器端了解的不多,可能叙述有误)若每次访问都带上用户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操作
都可以。