美好的一天!
我的应用程序使用简单的http客户端 - 服务器通信,与客户端的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));
}
}
之后,我请求我列出的设备,与当前用户有关。此刻,我有一个来自响应标题的cookei。 auth请求上的完整标头响应输出:
在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放到设备列表请求的标题中,但作为回应我看到:{&#34; status&#34;:false,&#34;错误&#34;:&#34;没有授权&#34 ;}
在桌面PC上的Chrome浏览器中收到的设备列表已经过时 - 问题出在Android上。
拜托,您能告诉我,我的代码有什么问题吗?也许我在设置标题时错了???
发送请求程序代码:
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);
}
答案 0 :(得分:5)
如果您不需要与Android兼容&lt; 2.3您只需要在活动或应用程序的onCreate中添加这行代码。这将激活所有httpURL连接的默认cookieManager。
CookieHandler.setDefault(new CookieManager());
希望得到这个帮助。
如果您需要更多向后兼容性,则还需要针对HttpClient进行Cookie管理
编辑:在后一种情况下,请按照以下答案传递自定义HttpClientStack:https://stackoverflow.com/a/21271347
答案 1 :(得分:1)
我遇到了Volley标题操作的问题。 检查Volley内部的HurlStack源代码。
Volley中的标题放在Map中,有时候(我仍然不知道为什么),Volley逐个收集相同键的标题(在你的情况下为Set-Cookie)(首先它将是这个PHPSESSION,然后它会将此路径作为Set-Cookie的一部分。由于这是一张地图,第一张被覆盖,你得不到你想要的东西。
我的建议是更改HurlStack的源代码,以便在列表中或使用不同的密钥(Set-Cookie1,Set-Cookie2,..)获取这些标头。
另外看看RetroFit它处理这个非常好。唯一的问题是,使用RetroFit,您无法取消请求。
希望这有帮助。