Volley 忽略 Cookie header 请求
Volley ignores Cookie header request
美好的一天!
我的应用程序使用简单的 http client-server 通信,在客户端与 Volley 库建立。首先,我启动授权请求:
public class AuthenticationRequest extends StringRequest {
private static final String TAG = AuthenticationRequest.class.getSimpleName();
private String login;
private String password;
public AuthenticationRequest(int method,
String url,
Response.Listener<String> listener,
Response.ErrorListener errorListener) {
super(method, url, listener, errorListener);
}
public void setLogin(String login) {
this.login = login;
}
public void setPassword(String password) {
this.password = password;
}
@Override
protected Map<String, String> getParams() {
HashMap<String, String> parameters = new HashMap<>();
parameters.put("login", login);
parameters.put("password", password);
return parameters;
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
for (Map.Entry<String, String> entry : response.headers.entrySet()) {
Log.d(TAG, entry.getKey() + " -- " + entry.getValue());
}
String sessionId = response.headers.get("Set-Cookie");
return Response.success(sessionId, HttpHeaderParser.parseCacheHeaders(response));
}
}
紧接着我请求我的设备列表,与当前用户相关联。此刻我有一个来自响应 headers 的 cookei。身份验证请求的完整 headers 响应输出:
- Cache-Control -- no-store, no-cache, must-revalidate, post-check=0, pre-check=0
- 连接 -- keep-alive
- Content-Length -- 16
- Content-Type -- text/html;字符集=utf-8
- 日期 -- 2015 年 9 月 18 日,星期五 06:15:57 GMT
- 到期 -- 1981 年 11 月 19 日星期四 08:52:00 GMT
- 编译指示 -- no-cache
- 服务器 -- nginx
- Set-Cookie -- PHPSESSID=osurmkq1fmnj462c3hk76l1405;路径=/
- X-Android-Received-Millis -- 1442553247146
- X-Android-Sent-Millis -- 1442553247096
- X-Powered-By -- PHP/5.3.27
在 Auth 请求的 onResponce 回调中,我将 Set-Cookie 值作为 sessionId 并启动 DeviceListRequest:
public class DeviceListRequest extends StringRequest {
private static final String TAG = DeviceListRequest.class.getSimpleName();
private String phpSessId;
public DeviceListRequest(int method,
String url,
Response.Listener<String> listener,
Response.ErrorListener errorListener) {
super(method, url, listener, errorListener);
}
public void setPhpSessId(String phpSessId) {
this.phpSessId = phpSessId;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
Log.d(TAG, phpSessId);
headers.put("Cookie", phpSessId);
return headers;
}
}
我在这里将 sessionId 放入设备列表请求的 headers,但作为响应,我看到了这个:{"status":false,"error":"No authorization"}
在 Chrome 中,桌面 PC 上的浏览器按预期收到设备列表 - 问题出在 Android。
拜托,你能告诉我,我的代码有什么问题吗?也许我设置错了 header???
发送请求程序代码:
public void authenticationRequest(String login, String password) {
final AuthenticationRequest request = new AuthenticationRequest(Request.Method.GET,
AUTHENTICATION_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "Response: " + response);
phpSessId = response;
deviceListRequest(phpSessId);
}
},
this);
request.setLogin(login);
request.setPassword(password);
requestQueue.add(request);
}
public void deviceListRequest(String phpSessId) {
DeviceListRequest request = new DeviceListRequest(Request.Method.GET,
DEVICE_LIST_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "Response: " + response);
}
},
this);
request.setPhpSessId(phpSessId);
requestQueue.add(request);
}
如果您不需要与 Android < 2.3 兼容,您只需在 activity 或应用程序的 onCreate 中添加这行代码。这将为所有 httpURL 连接激活默认的 cookieManager。
CookieHandler.setDefault(new CookieManager());
希望对您有所帮助。
如果您需要更多的向后兼容性,您还需要 HttpClient 的 Cookie 管理
编辑:在后一种情况下,请按照此答案传递自定义 HttpClientStack:
Volley header 操作有问题,我 运行 也参与其中。
检查 Volley 中的 HurlStack 的源代码。
Headers 里面的 Volley 被放在 Map 里面,有时(我仍然不知道为什么),Volley 收集相同键的 headers(在你的情况下 Set-Cookie)一个接一个(首先是这个 PHPSESSION,然后它将得到这个路径的一部分 Set-Cookie)。由于这是一个地图,第一个被覆盖,你得不到你想要的。
我的建议是更改 HurlStack 的源代码,以便在列表中或使用不同的键(Set-Cookie1、Set-Cookie2、.. ).
另外看看 RetroFit,它处理得非常好。唯一的问题是使用 RetroFit 你无法取消请求。
希望这对您有所帮助。
美好的一天!
我的应用程序使用简单的 http client-server 通信,在客户端与 Volley 库建立。首先,我启动授权请求:
public class AuthenticationRequest extends StringRequest {
private static final String TAG = AuthenticationRequest.class.getSimpleName();
private String login;
private String password;
public AuthenticationRequest(int method,
String url,
Response.Listener<String> listener,
Response.ErrorListener errorListener) {
super(method, url, listener, errorListener);
}
public void setLogin(String login) {
this.login = login;
}
public void setPassword(String password) {
this.password = password;
}
@Override
protected Map<String, String> getParams() {
HashMap<String, String> parameters = new HashMap<>();
parameters.put("login", login);
parameters.put("password", password);
return parameters;
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
for (Map.Entry<String, String> entry : response.headers.entrySet()) {
Log.d(TAG, entry.getKey() + " -- " + entry.getValue());
}
String sessionId = response.headers.get("Set-Cookie");
return Response.success(sessionId, HttpHeaderParser.parseCacheHeaders(response));
}
}
紧接着我请求我的设备列表,与当前用户相关联。此刻我有一个来自响应 headers 的 cookei。身份验证请求的完整 headers 响应输出:
- Cache-Control -- no-store, no-cache, must-revalidate, post-check=0, pre-check=0
- 连接 -- keep-alive
- Content-Length -- 16
- Content-Type -- text/html;字符集=utf-8
- 日期 -- 2015 年 9 月 18 日,星期五 06:15:57 GMT
- 到期 -- 1981 年 11 月 19 日星期四 08:52:00 GMT
- 编译指示 -- no-cache
- 服务器 -- nginx
- Set-Cookie -- PHPSESSID=osurmkq1fmnj462c3hk76l1405;路径=/
- X-Android-Received-Millis -- 1442553247146
- X-Android-Sent-Millis -- 1442553247096
- X-Powered-By -- PHP/5.3.27
在 Auth 请求的 onResponce 回调中,我将 Set-Cookie 值作为 sessionId 并启动 DeviceListRequest:
public class DeviceListRequest extends StringRequest {
private static final String TAG = DeviceListRequest.class.getSimpleName();
private String phpSessId;
public DeviceListRequest(int method,
String url,
Response.Listener<String> listener,
Response.ErrorListener errorListener) {
super(method, url, listener, errorListener);
}
public void setPhpSessId(String phpSessId) {
this.phpSessId = phpSessId;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
Log.d(TAG, phpSessId);
headers.put("Cookie", phpSessId);
return headers;
}
}
我在这里将 sessionId 放入设备列表请求的 headers,但作为响应,我看到了这个:{"status":false,"error":"No authorization"}
在 Chrome 中,桌面 PC 上的浏览器按预期收到设备列表 - 问题出在 Android。
拜托,你能告诉我,我的代码有什么问题吗?也许我设置错了 header???
发送请求程序代码:
public void authenticationRequest(String login, String password) {
final AuthenticationRequest request = new AuthenticationRequest(Request.Method.GET,
AUTHENTICATION_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "Response: " + response);
phpSessId = response;
deviceListRequest(phpSessId);
}
},
this);
request.setLogin(login);
request.setPassword(password);
requestQueue.add(request);
}
public void deviceListRequest(String phpSessId) {
DeviceListRequest request = new DeviceListRequest(Request.Method.GET,
DEVICE_LIST_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "Response: " + response);
}
},
this);
request.setPhpSessId(phpSessId);
requestQueue.add(request);
}
如果您不需要与 Android < 2.3 兼容,您只需在 activity 或应用程序的 onCreate 中添加这行代码。这将为所有 httpURL 连接激活默认的 cookieManager。
CookieHandler.setDefault(new CookieManager());
希望对您有所帮助。
如果您需要更多的向后兼容性,您还需要 HttpClient 的 Cookie 管理
编辑:在后一种情况下,请按照此答案传递自定义 HttpClientStack:
Volley header 操作有问题,我 运行 也参与其中。 检查 Volley 中的 HurlStack 的源代码。
Headers 里面的 Volley 被放在 Map 里面,有时(我仍然不知道为什么),Volley 收集相同键的 headers(在你的情况下 Set-Cookie)一个接一个(首先是这个 PHPSESSION,然后它将得到这个路径的一部分 Set-Cookie)。由于这是一个地图,第一个被覆盖,你得不到你想要的。
我的建议是更改 HurlStack 的源代码,以便在列表中或使用不同的键(Set-Cookie1、Set-Cookie2、.. ).
另外看看 RetroFit,它处理得非常好。唯一的问题是使用 RetroFit 你无法取消请求。
希望这对您有所帮助。