您的位置:首页 > 其它

使用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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: