Good day!
My app uses simple http client-server communication, established with Volley library on client side. First, i fire up an authorization request:
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));
}
}
Right after that i requests i list of devices, assiciated with current user. At this moment i have a cookei from response headers. Full headers response output on auth request:
- Cache-Control -- no-store, no-cache, must-revalidate, post-check=0, pre-check=0
- Connection -- keep-alive
- Content-Length -- 16
- Content-Type -- text/html; charset=utf-8
- Date -- Fri, 18 Sep 2015 06:15:57 GMT
- Expires -- Thu, 19 Nov 1981 08:52:00 GMT
- Pragma -- no-cache
- Server -- nginx
- Set-Cookie -- PHPSESSID=osurmkq1fmnj462c3hk76l1405; path=/
- X-Android-Received-Millis -- 1442553247146
- X-Android-Sent-Millis -- 1442553247096
- X-Powered-By -- PHP/5.3.27
in onResponce callback of Auth request i take Set-Cookie value as sessionId and fire up a 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;
}
}
Here i put sessionId to headers of device list request, but in response i see this: {"status":false,"error":"No authorization"}
In Chrome browser on Desktop PC recieves list of devices as expeceted - the problem is on Android.
Please, Can you tell me, what's the problem with my code? Maybe i'm wrong at setting header???
Code of sending requests procedure:
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);
}
If you do not need compatibility with Android < 2.3 you just need to add this line of code in your onCreate of the activity or the application. That will activate default cookieManager for all httpURLconnections.
CookieHandler.setDefault(new CookieManager());
Hope this help.
If you need more backwards compatibility you need Cookie management also for HttpClient
Edit:in this latter case follow this answer to pass a custom HttpClientStack: https://stackoverflow.com/a/21271347
There is a problem with Volley header manipulation that I ran into also. Check the source code of HurlStack that comes inside Volley.
Headers inside Volley are put inside Map and sometimes (I still don't know why), Volley gathers headers of the same key (in your case Set-Cookie) one by one ( first it would be this PHPSESSION, and then it will get this path part of your Set-Cookie). As this is a Map, the first one gets overwritten, and you dont get what you want.
My suggestion is to alter the source code of HurlStack in order to get those headers in a list or with different keys (Set-Cookie1, Set-Cookie2, ..).
Also take a look at RetroFit it handles this really nice. Only thing is that with RetroFit you don't get the possibility of canceling the requests.
Hope this helps.
来源:https://stackoverflow.com/questions/32645823/volley-ignores-cookie-header-request