在Android排球库中使用Cookie

有没有人知道如何使用com.android.volley库将会话cookie附加到请求中? 当我登录到网站时,它会给我一个会话cookie。 浏览器会将该cookie发送回任何后续请求。 Volley似乎没有这样做,至少不会自动。

谢谢。


Volley本身并不实际发出HTTP请求,因此不直接管理Cookies。 而是使用HttpStack的一个实例来执行此操作。 有两个主要的实现:

  • HurlStack:引擎盖下使用HttpUrlConnection
  • HttpClientStack:引擎盖下使用Apache HttpClient
  • Cookie管理是这些HttpStack的责任。 他们每个人都以不同方式处理Cookie

    如果你需要支持<2.3,那么你应该使用HttpClientStack:

    配置一个HttpClient实例,并将其传递给Volley以供它在底层使用:

    // If you need to directly manipulate cookies later on, hold onto this client
    // object as it gives you access to the Cookie Store
    DefaultHttpClient httpclient = new DefaultHttpClient();
    
    CookieStore cookieStore = new BasicCookieStore();
    httpclient.setCookieStore( cookieStore );
    
    HttpStack httpStack = new HttpClientStack( httpclient );
    RequestQueue requestQueue = Volley.newRequestQueue( context, httpStack  );
    

    与手动将Cookie插入标头的优点是,您可以获得实际的Cookie管理。 您商店中的Cookie将正确响应过期或更新它们的HTTP控件。

    我已经更进了一步,将BasicCookieStore分类,以便我可以自动将Cookie保存到磁盘。

    然而! 如果你不需要支持旧版本的Android。 只需使用这种方法:

    // CookieStore is just an interface, you can implement it and do things like
    // save the cookies to disk or what ever.
    CookieStore cookieStore = new MyCookieStore();
    CookieManager manager = new CookieManager( cookieStore, CookiePolicy.ACCEPT_ALL );
    CookieHandler.setDefault( manager  );
    
    // Optionally, you can just use the default CookieManager
    CookieManager manager = new CookieManager();
    CookieHandler.setDefault( manager  );
    

    HttpURLConnection将隐式地从中查询CookieManager。 HttpUrlConnection的性能也更高,并且在实施和使用IMO方面稍微清晰一些。


    vmirinov是对的!

    这是我解决问题的方法:

    请求类:

    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;
        }
    }
    

    和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());
            }
        }
    
    }
    

    Volley的默认HTTP传输代码是HttpUrlConnection 。 如果我正确阅读文档,则需要选择自动会话cookie支持:

    CookieManager cookieManager = new CookieManager();
    CookieHandler.setDefault(cookieManager);
    

    另请参见应Cookie的HttpURLConnection自动处理会话Cookie?

    链接地址: http://www.djcxy.com/p/87915.html

    上一篇: Using cookies with Android volley library

    下一篇: How to check if current thread is not main thread