使用Volley实现session会话保持
2015-12-19 14:25
423 查看
使用volley很久了,关于volley处理网络请求,其确实封装简化了过程,然而有些功能还是本身不支持,需要自己扩展配置。比如本地保存服务端返回的cookie数据。
volley中的Request类,代表一个网络请求的抽象类,我们常常用到的JsonObjectRequest和StringObjectRequest都是继承的它,我们通过构建一个Request类的非抽象子类(StringRequest、JsonRequest、ImageRequest 或自定义)对象,并将其加入到·RequestQueue·中来完成一次网络请求操作。
Volley 支持 8 种 Http 请求方式 GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, PATCH
Request 类中包含了请求 url,请求请求方式,请求 Header,请求 Body,请求的优先级等信息。因为是抽象类,子类必须重写的两个方法:
abstract protected Response parseNetworkResponse(NetworkResponse response);
此方法意思是将网络返回的字节数据转换成想要的类型(如String,Onject或者其他)
abstract protected void deliverResponse(T response);
此方法将已经解析成想要的类型的内容传递给它们的监听回调。
要想保存session,可见我们在请求的时候需要保存到sharedpreference中.一般情况下我们在application中新new 一个 RequestQueue 就可以处理所有网络请求,这样RequestQueue的生命周期维护就交给application了,保存cookie的工具方法可以在application中完成。
代码如下:
public class CustomApplication extends Application { private static final String SET_COOKIE_KEY = "Set-Cookie"; private static final String COOKIE_KEY = "Cookie"; private static final String SESSION_COOKIE = "JSESSIONID"; private static CustomApplication instance; private RequestQueue requestQueue; private SharedPreferences preferences; public static CustomApplication newInstance() { return instance; } @Override public void onCreate() { super.onCreate(); instance = this; preferences = PreferenceManager.getDefaultSharedPreferences(this); requestQueue = Volley.newRequestQueue(this); } public RequestQueue getRequestQueue() { return requestQueue; } /** * 检查返回的Response header中有没有session * @param responseHeaders Response Headers. */ public final void checkSessionCookie(Map<String, String> responseHeaders) { if (responseHeaders.containsKey(SET_COOKIE_KEY) && responseHeaders.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) { String cookie = responseHeaders.get(SET_COOKIE_KEY); if (cookie.length() > 0) { String[] splitCookie = cookie.split(";"); String[] splitSessionId = splitCookie[0].split("="); cookie = splitSessionId[1]; SharedPreferences.Editor prefEditor = preferences.edit(); prefEditor.putString(SESSION_COOKIE, cookie); prefEditor.commit(); } } } /** * 添加session到Request header中 */ public final void addSessionCookie(Map<String, String> requestHeaders) { String sessionId = preferences.getString(SESSION_COOKIE, ""); if (sessionId.length() > 0) { StringBuilder builder = new StringBuilder(); builder.append(SESSION_COOKIE); builder.append("="); builder.append(sessionId); if (requestHeaders.containsKey(COOKIE_KEY)) { builder.append("; "); builder.append(requestHeaders.get(COOKIE_KEY)); } requestHeaders.put(COOKIE_KEY, builder.toString()); } }
有了保存cookie和读取cookie的工具类,就可以自定义Request了:
1.下面代码以JsonObject为例:
public class SessionStoreRequest extends JsonObjectRequest { public SessionStoreRequest(int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) { super(method, url, jsonRequest, listener, errorListener); } public SessionStoreRequest(String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) { super(url, jsonRequest, listener, errorListener); } @Override protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) { // 检查本地是否有session.如果没哦有,就将header中的session数据保存到本地 CustomApplication.newInstance().checkSessionCookie(response.headers); JSONObject jb =null; try { String parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); jb = new JSONObject(parsed); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } return Response.success(jb, HttpHeaderParser.parseCacheHeaders(response)); } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = super.getHeaders(); if (headers == null || headers.equals(Collections.emptyMap())) { headers = new HashMap<String, String>(); } CustomApplication.newInstance().addSessionCookie(headers); return headers; } }
2.使用POST方法提交时候的Request,需要特别注意下,重写 getParams()方法,下麦呢以返回String类型数据为例:
public class PostStringRequest extends Request<String> { private final Response.Listener<String> mListener; private Map<String, String> mParams; public PostStringRequest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; } public PostStringRequest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener) { this(Method.GET, url, listener, errorListener); } public PostStringRequest(String url, Map<String, String> mParams, Response.Listener<String> listener, Response.ErrorListener errorListener) { this(Method.POST, url, listener, errorListener); this.mParams =mParams; } @Override protected void deliverResponse(String response) { mListener.onResponse(response); } @Override protected Response<String> parseNetworkResponse(NetworkResponse response) { CustomApplication.newInstance().checkSessionCookie(response.headers); 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)); } @Override public Map<String, String> getParams() { return mParams; } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = super.getHeaders(); if (headers == null || headers.equals(Collections.emptyMap())) { headers = new HashMap<String, String>(); } CustomApplication.newInstance().addSessionCookie(headers); return headers; }
在使用的时候:
Map<String, String> map = new HashMap<String, String>(); map.put("useName", "tom"); map.put("userAge", "16"); PostStringRequest jr = new PostStringRequest(basicUrl, map,new Response.Listener<String>() { @Override public void onResponse(String response) { Log.i(TAG, response.toString()); autoTenderSafePass.setText(""); BaseBean resultBean = new Gson().fromJson(response.toString(), BaseBean.class); if (resultBean.getRcd().equals("R0001")) { Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show(); } else if(resultBean.getRcd().equals("S0001")){ Toast.makeText(MainActivity.this, "保存失败,请稍后重试", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(AutoInvestActivity.this, resultBean.getRmg(), Toast.LENGTH_SHORT).show(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.i(TAG, error.getMessage()); } }); CustomApplication.newInstance().getRequestQueue().add(jr);
相关文章推荐
- mybatis报错:批量设置别名时
- 新版数据库分页方法(Sql server2012)
- xamarin for android 生成时“java.exe已退出 代码为1”
- Bash中的$符号
- JavaScript 三种不同位置代码的写法
- golang SQLDriverConnect: {IM005} [Microsoft][ODBC 驱动程序管理器] 驱动程序的 SQLAllocHandle on SQL_HANDLE_DBC 失败
- 性能测试监控工具nmon安装及使用方法
- GPT分区结构
- CSS样式覆盖规则
- android中的EventBus
- 【转】ATA Secure Erase
- <LeetCode OJ> 21. Merge Two Sorted Lists
- 数据库_Mysql_mysql中char,varchar与text类型的区别和选用
- 过生日,也要学学哈,这次是SHELL的GETOPTS
- Hbase 分布查询 - 应用后台程序控制分页
- 爱奇艺宣布正式启动动漫IP制作开发计划
- Android开发——listview中嵌套checkBox复选框实现单选、全选删除列表内容
- 我的springmvc简单版
- 20135326王亦可信息安全系统设计基础期末总结
- 依据周次获取周次的日期范围