androidandroid-volley

Using cookies with Android volley library


Does anybody know how to attach a session cookie to the request using com.android.volley library? When I log in to a web site it gives me a session cookie. Browser would send that cookie back with any subsequent request. Volley does not seem to do that, at least not automatically.

Thanks.


Solution

  • vmirinov is right!

    Here is how I solved the problem:

    Request class:

    public class StringRequest extends com.android.volley.toolbox.StringRequest {
    
        private final Map<String, String> _params;
    
        /**
         * @param method
         * @param url
         * @param params
         *            A {@link HashMap} to post with the request. Null is allowed
         *            and indicates no parameters will be posted along with request.
         * @param listener
         * @param errorListener
         */
        public StringRequest(int method, String url, Map<String, String> params, Listener<String> listener,
                ErrorListener errorListener) {
            super(method, url, listener, errorListener);
    
            _params = params;
        }
    
        @Override
        protected Map<String, String> getParams() {
            return _params;
        }
    
        /* (non-Javadoc)
         * @see com.android.volley.toolbox.StringRequest#parseNetworkResponse(com.android.volley.NetworkResponse)
         */
        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {
            // since we don't know which of the two underlying network vehicles
            // will Volley use, we have to handle and store session cookies manually
            MyApp.get().checkSessionCookie(response.headers);
    
            return super.parseNetworkResponse(response);
        }
    
        /* (non-Javadoc)
         * @see com.android.volley.Request#getHeaders()
         */
        @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>();
            }
    
            MyApp.get().addSessionCookie(headers);
    
            return headers;
        }
    }
    

    and MyApp:

    public class MyApp extends Application {
        private static final String SET_COOKIE_KEY = "Set-Cookie";
        private static final String COOKIE_KEY = "Cookie";
        private static final String SESSION_COOKIE = "sessionid";
    
        private static MyApp _instance;
      private RequestQueue _requestQueue;
      private SharedPreferences _preferences;
    
        public static MyApp get() {
            return _instance;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            _instance = this;
                _preferences = PreferenceManager.getDefaultSharedPreferences(this);
            _requestQueue = Volley.newRequestQueue(this);
        }
    
        public RequestQueue getRequestQueue() {
            return _requestQueue;
        }
    
    
        /**
         * Checks the response headers for session cookie and saves it
         * if it finds it.
         * @param headers Response Headers.
         */
        public final void checkSessionCookie(Map<String, String> headers) {
            if (headers.containsKey(SET_COOKIE_KEY)
                    && headers.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) {
                    String cookie = headers.get(SET_COOKIE_KEY);
                    if (cookie.length() > 0) {
                        String[] splitCookie = cookie.split(";");
                        String[] splitSessionId = splitCookie[0].split("=");
                        cookie = splitSessionId[1];
                        Editor prefEditor = _preferences.edit();
                        prefEditor.putString(SESSION_COOKIE, cookie);
                        prefEditor.commit();
                    }
                }
        }
    
        /**
         * Adds session cookie to headers if exists.
         * @param headers
         */
        public final void addSessionCookie(Map<String, String> headers) {
            String sessionId = _preferences.getString(SESSION_COOKIE, "");
            if (sessionId.length() > 0) {
                StringBuilder builder = new StringBuilder();
                builder.append(SESSION_COOKIE);
                builder.append("=");
                builder.append(sessionId);
                if (headers.containsKey(COOKIE_KEY)) {
                    builder.append("; ");
                    builder.append(headers.get(COOKIE_KEY));
                }
                headers.put(COOKIE_KEY, builder.toString());
            }
        }
    
    }