在 Android volley 库中使用 cookie

Posted

技术标签:

【中文标题】在 Android volley 库中使用 cookie【英文标题】:Using cookies with Android volley library 【发布时间】:2013-05-21 22:41:54 【问题描述】:

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

谢谢。

【问题讨论】:

这应该是底层 HTTP 传输层的函数(例如,HttpUrlConnectionHttpClient),而不是 Volley 本身。您是否尝试过直接使用其中之一? CommonsWare,我没有。凌空抽射的全部目的不是隐藏这种复杂性吗?我经历了凌空选择,找不到任何对底层的访问。您对如何访问底层有什么建议吗?谢谢。 “截击的全部目的不就是隐藏这种复杂性吗?” ——正如我所写,AFAIK 会话 cookie 由 HTTP 传输代码处理。我直接尝试其中一种传输的建议是查看您的问题是否仍然存在,在这种情况下,这不是 Volley 的问题,而是 Android 或您的服务器中的问题。 “你对如何访问底层有什么建议吗?” ——暂时把Volley放在一边,自己写到“底层”。尤其是HttpUrlConnection,已经存在了大约 15 年,并且有很多如何使用它的示例。 由于cookie只是一个普通的http头,你可以使用NetworkResponse.headers字段保存这个头,然后通过覆盖Request.getHeaders方法将它附加到每个后续请求 对于那些关注这个帖子的人,我有一个后续问题。 ***.com/questions/18413846/… 【参考方案1】:

Volley 本身并不实际发出 HTTP 请求,因此不直接管理 Cookie。它改为使用 HttpStack 的实例来执行此操作。主要有两种实现方式:

HurlStack:在后台使用 HttpUrlConnection HttpClientStack:在后台使用 Apache HttpClient

Cookie 管理是那些 HttpStacks 的责任。他们各自处理 Cookie 的方式不同。

如果你需要支持

配置一个 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。

【讨论】:

这对我有用。我最后只使用了默认的 CookieManager。相反,调用 CookieHandler.getDefault().put() 需要 Map>。 put() 的默认实现将 cookie 从映射中解析出来,并要求键是(不区分大小写)“set-cookie”或“set-cookie2”。必须检查来源才能找出答案。 @Adam,谢谢,我也使用了默认的 CookieManager,标题现在是正确的。但是当我重定向到另一个活动时,即使我设置了活动的 cookiemanager onCreate,这些标头也不再是请求的一部分,有没有办法让它在活动之间持久化? 希望你也与我们分享你的MyCookieStore 班级 谢谢。最简单最好。尝试了使用默认 CookieManager 的第二种方法,它起作用了。【参考方案2】:

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;
    

和我的应用程序:

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


【讨论】:

应该注意,标头可能会返回为“Set-Cookie”,或者“set-cookie” - 在这种情况下,此代码会中断。 对于那些关注这个问题的人,我有一个后续问题。 ***.com/questions/18413846/… 另外,存储 cookie 的优点是共享偏好。为什么不将其存储为静态类成员? @TestBest,存储在首选项中使 cookie 在应用程序退出时仍然存在。如果您希望会话 cookie 持续更长时间然后运行一个应用程序,您可以选择。 请注意,如果有多个 cookie,则会有多个“Set-Cookie”标头,并且由于响应标头是 Map,您只会得到第一个!是的,这个 Volley 库缺少一些东西。在这个问题上讨论过:***.com/questions/18998361/…【参考方案3】:

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

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

另见Should HttpURLConnection with CookieManager automatically handle session cookies?

【讨论】:

默认传输实现实际上取决于特定设备的 android 版本(HttpUrlConnection 用于Gingerbread 及更高版本,HttpClient 用于以前版本),您不应该依赖它 这就是我的理解。如果 volley 选择 HttpUrlConnection,Commons Ware 的答案是正确的。这就是为什么我希望凌空处理它。我离开电脑几天了。我会检查一些继承是否有帮助。 注意默认传输是在 Volley 助手类 android.googlesource.com/platform/frameworks/volley/+/master/… 中指定的,如果你没有明确地将 HttpStack 传递给 newRequestQueue。无论使用 HurlStack 还是 HttpClientStack ,编写自己的 newRequestQueue 辅助方法版本都会很简单。 好的。那么有没有办法为 HttpURLConnection 和 HttpClient 两种类型的客户端选择会话 cookie?请参阅我的后续问题:***.com/questions/18413846/… 目前Gingerbread以下Android用户占比为2.2%。我个人不关心他们。所以我同意 CommonsWare 并在 HurlStack 构造函数中添加了CookieHandler.setDefault(new CookieManager( null, CookiePolicy.ACCEPT_ALL ) );。效果很好。【参考方案4】:

大家可以在AppController.javaonCreate 方法中试试这个

  CookieHandler.setDefault(new CookieManager());

希望它能节省开发人员的时间。我在调试和寻找合适的解决方案上浪费了四个小时。

【讨论】:

谢谢,这么简单!【参考方案5】:

如果有多个“Set-Cookie”标头,@Rastio 解决方案将不起作用。我包装了默认的 CookieManager cookie 存储,在添加 cookie 之前,我使用 Gson 将其保存在 SharedPreferences 中以序列化 cookie。

这是 cookie 存储包装的示例:

import android.content.Context;
import android.net.Uri;
import android.util.Log;

import com.google.gson.Gson;

import java.net.CookieManager;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.URI;
import java.util.List;

/**
 * Class that implements CookieStore interface. This class saves to SharedPreferences the session
 * cookie.
 *
 * Created by lukas.
 */
public class PersistentCookieStore implements CookieStore 

    private CookieStore mStore;
    private Context mContext;
    private Gson mGson;

    public PersistentCookieStore(Context context) 
        // prevent context leaking by getting the application context
        mContext = context.getApplicationContext();
        mGson = new Gson();

        // get the default in memory store and if there is a cookie stored in shared preferences,
        // we added it to the cookie store
        mStore = new CookieManager().getCookieStore();
        String jsonSessionCookie = Prefs.getJsonSessionCookie(mContext);
        if (!jsonSessionCookie.equals(Prefs.DEFAULT_STRING)) 
            HttpCookie cookie = mGson.fromJson(jsonSessionCookie, HttpCookie.class);
            mStore.add(URI.create(cookie.getDomain()), cookie);
        
    

    @Override
    public void add(URI uri, HttpCookie cookie) 
        if (cookie.getName().equals("sessionid")) 
            // if the cookie that the cookie store attempt to add is a session cookie,
            // we remove the older cookie and save the new one in shared preferences
            remove(URI.create(cookie.getDomain()), cookie);
            Prefs.saveJsonSessionCookie(mContext, mGson.toJson(cookie));
        

        mStore.add(URI.create(cookie.getDomain()), cookie);
    

    @Override
    public List<HttpCookie> get(URI uri) 
        return mStore.get(uri);
    

    @Override
    public List<HttpCookie> getCookies() 
        return mStore.getCookies();
    

    @Override
    public List<URI> getURIs() 
        return mStore.getURIs();
    

    @Override
    public boolean remove(URI uri, HttpCookie cookie) 
        return mStore.remove(uri, cookie);
    

    @Override
    public boolean removeAll() 
        return mStore.removeAll();
    

然后,使用刚刚在 CookieManager 中设置的 cookie 存储就可以了!

CookieManager cookieManager = new CookieManager(new PersistentCookieStore(mContext),
    CookiePolicy.ACCEPT_ORIGINAL_SERVER);
CookieHandler.setDefault(cookieManager);

【讨论】:

在 PersistentCookieStore 的构造函数中,我认为我们需要从 SharedPreferences 中获取存储的 cookie 列表(不仅仅是一个 cookie)。你怎么看?此外,我们也需要在每次更新 mStore 时更新 SharedPreferences。 @Lukas 你能详细说明你的例子吗?我的意思是您如何将这些多个 Cookie 保存在共享首选项中?【参考方案6】:

我知道这个帖子有点老了,但是我们最近遇到了这个问题,我们需要在服务器之间共享一个登录用户的会话,而服务器端解决方案开始要求客户端提供一个值,通过 cookie。 我们找到的一种解决方案是向RequestQueue对象添加一个参数,在实例化下面链接中的RequestQueue之前,方法getRequestQueue中的代码sn-p,并解决了问题,不知道如何,但它开始了上班。

访问http://woxiangbo.iteye.com/blog/1769122

public class App extends Application 

    public static final String TAG = App.class.getSimpleName();

    private static App         mInstance;

    public static synchronized App getInstance() 
        return App.mInstance;
    

    private RequestQueue mRequestQueue;

    public <T> void addToRequestQueue( final Request<T> req ) 
        req.setTag( App.TAG );
        this.getRequestQueue().add( req );
    

    public <T> void addToRequestQueue( final Request<T> req, final String tag ) 
        req.setTag( TextUtils.isEmpty( tag ) ? App.TAG : tag );
        this.getRequestQueue().add( req );
    

    public void cancelPendingRequests( final Object tag ) 
        if ( this.mRequestQueue != null ) 
            this.mRequestQueue.cancelAll( tag );
        
    

    public RequestQueue getRequestQueue() 

        if ( this.mRequestQueue == null ) 


            DefaultHttpClient mDefaultHttpClient = new DefaultHttpClient();

            final ClientConnectionManager mClientConnectionManager = mDefaultHttpClient.getConnectionManager();
            final HttpParams mHttpParams = mDefaultHttpClient.getParams();
            final ThreadSafeClientConnManager mThreadSafeClientConnManager = new ThreadSafeClientConnManager( mHttpParams, mClientConnectionManager.getSchemeRegistry() );

            mDefaultHttpClient = new DefaultHttpClient( mThreadSafeClientConnManager, mHttpParams );

            final HttpStack httpStack = new HttpClientStack( mDefaultHttpClient );

            this.mRequestQueue = Volley.newRequestQueue( this.getApplicationContext(), httpStack );
        

        return this.mRequestQueue;
    

    @Override
    public void onCreate() 
        super.onCreate();
        App.mInstance = this;
    

//设置令牌值

ObjectRequest.setHeader( "Cookie", "JSESSIONID=" + tokenValueHere );

【讨论】:

你在哪里添加cookie? 非常感谢 ObjectRequest.setHeader( "Cookie", "JSESSIONID=" + tokenValueHere );这条线拯救了我的一天@AndersonK【参考方案7】:

使用此方法将 Volley 与 cookie 一起使用以:

    仅使用在 Apache 2 许可下经过良好测试的代码 同时提出尽可能多的请求 确保 cookie 保留在设备上 不必重新发明***

我的服务器使用 cookie 进行身份验证,显然我想确保 cookie 在设备上持续存在。所以我的解决方案是使用来自Asynchronous Http Client for Android 的PersistentCookieStore 和SerializableCookie 类。

首先,为了启用并发请求,需要一个适用于 Android 的 Apache HttpClient v4.3 端口 - 系统自带的端口已经过时。更多信息here。我使用 Gradle,所以我是这样导入的:

dependencies 
    compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.3'

获取 RequestQueue 的函数(在我扩展 Application 的类中):

private RequestQueue mRequestQueue;
private CloseableHttpClient httpClient;

...

public RequestQueue getRequestQueue() 
    if (mRequestQueue == null) 
        httpClient = HttpClients.custom()
            .setConnectionManager(new PoolingHttpClientConnectionManager())
            .setDefaultCookieStore(new PersistentCookieStore(getApplicationContext()))
            .build();
        mRequestQueue = Volley.newRequestQueue(getApplicationContext(), new HttpClientStack(httpClient));
    
    return mRequestQueue;

这就是我排队请求的方式

public <T> void addToRequestQueue(Request<T> req, String tag) 
    req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
    getRequestQueue().add(req);

就是这样!

【讨论】:

setDefaultCookieStore 不能将 PersistentCookieStore 作为参数 不确定你的意思 - 这就是我运行的确切代码。它运作良好。不过,这个答案可能与 Volley 的早期版本有关【参考方案8】:

姜饼+安卓版本:

还有另一种简单的方法来维护 cookie 会话,那就是将这一行添加到使用 APPLICATION 类扩展的类中:

CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

【讨论】:

【参考方案9】:

如果您已经开始使用 Loopj 库来实现您的应用程序,您会注意到您不能在 Volley.newRequestQUeue() 中使用新的 HttpClient 实例,因为您会收到关于未关闭先前连接等的各种错误。

类似的错误:

java.lang.IllegalStateException: No wrapped connection

Invalid use of SingleClientConnManager: connection still allocated.

现在有时重构所有旧 API 调用并使用 volley 重写它们需要时间,但您可以同时使用 volley 和 loopj 并在这两者之间共享一个 cookiestore,直到您将所有内容都写入 volley(使用 volley 而不是loopj,它好多了:))。

这就是你可以从 loopj 与 volley 共享 HttpClient 和 CookieStore 的方法。

// For example you initialize loopj first
private static AsyncHttpClient client = new AsyncHttpClient();
sCookieStore = new PersistentCookieStore(getSomeContextHere());
client.setTimeout(DEFAULT_TIMEOUT);
client.setMaxConnections(12);
client.setCookieStore(sCookieStore);
client.setThreadPool(((ThreadPoolExecutor) Executors.newCachedThreadPool()));

public static RequestQueue getRequestQueue()
    if(mRequestQueue == null)

    HttpClient httpclient = KkstrRestClient.getClient().getHttpClient();

    ((AbstractHttpClient) httpclient).setCookieStore( ApplicationController.getCookieStore() );

    HttpStack httpStack = new HttpClientStack(httpclient);

    mRequestQueue = Volley.newRequestQueue(getContext(), httpStack);
    

    return mRequestQueue;

这发生在我身上,我们开始使用 loopj。经过 50 000 行代码并发现 loopj 并不总是像预期的那样工作,我们决定改用 Volley。

【讨论】:

干杯,你让我走上了修复令人愤怒的错误的正确道路。我在我的应用程序中同时使用 loopj 和 volley 并且两者都需要(不要问!)。你的确切答案没有用,但这个答案确实有效,同样的想法,只是为 Volley cookie 获得了一个线程安全的 DefaultHttpClient:***.com/a/6737645/467509【参考方案10】:

@CommonsWare 的答案是我会使用的答案。但是,看起来 KitKat 有一些 bugs 完成后(当您使用自定义 CookieStore 创建 CookieManager 时,如果您想要持久性 Cookie,则需要该 CookieStore)。 考虑到无论使用的CookieStore 的实现如何,Volley 都会抛出一个NullpointerException,我必须创建自己的CookieHandler...如果你觉得它有帮助就使用它。

public class MyCookieHandler extends CookieHandler 

private static final String VERSION_ZERO_HEADER = "Set-cookie";

private static final String VERSION_ONE_HEADER = "Set-cookie2";
private static final String COOKIE_HEADER = "Cookie";

private static final String COOKIE_FILE = "Cookies";
private Map<String, Map<String, HttpCookie>> urisMap;

private Context context;

public MyCookieHandler(Context context) 

    this.context = context;
    loadCookies();



@SuppressWarnings("unchecked")
private void loadCookies() 
    File file = context.getFileStreamPath(COOKIE_FILE);
    if (file.exists())
        try 

            FileInputStream fis = context.openFileInput(COOKIE_FILE);
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    fis));
            String line = br.readLine();
            StringBuilder sb = new StringBuilder();
            while (line != null) 
                sb.append(line);
                line = br.readLine();
            
            Log.d("MyCookieHandler.loadCookies", sb.toString());
            JSONObject jsonuris = new JSONObject(sb.toString());
            urisMap = new HashMap<String, Map<String, HttpCookie>>();
            Iterator<String> jsonurisiter = jsonuris.keys();

            while (jsonurisiter.hasNext()) 
                String prop = jsonurisiter.next();
                HashMap<String, HttpCookie> cookiesMap = new HashMap<String, HttpCookie>();
                JSONObject jsoncookies = jsonuris.getJSONObject(prop);
                Iterator<String> jsoncookiesiter = jsoncookies.keys();
                while (jsoncookiesiter.hasNext()) 
                    String pprop = jsoncookiesiter.next();
                    cookiesMap.put(pprop,
                            jsonToCookie(jsoncookies.getJSONObject(pprop)));
                
                urisMap.put(prop, cookiesMap);

            

         catch (Exception e) 

            e.printStackTrace();
        
    else 
        urisMap = new HashMap<String, Map<String, HttpCookie>>();
    


@Override
public Map<String, List<String>> get(URI arg0,
        Map<String, List<String>> arg1) throws IOException 
    Log.d("MyCookieHandler.get",
            "getting Cookies for domain: " + arg0.getHost());
    Map<String, HttpCookie> cookies = urisMap.get(arg0.getHost());
    if (cookies != null)
        for (Entry<String, HttpCookie> cookie : cookies.entrySet()) 
            if (cookie.getValue().hasExpired()) 
                cookies.remove(cookie.getKey());
            
        

    if (cookies == null || cookies.isEmpty()) 
        Log.d("MyCookieHandler.get", "======");
        return Collections.emptyMap();
    
    Log.d("MyCookieHandler.get",
            "Cookie : " + TextUtils.join("; ", cookies.values()));
    Log.d("MyCookieHandler.get", "======");
    return Collections.singletonMap(COOKIE_HEADER, Collections
            .singletonList(TextUtils.join("; ", cookies.values())));


@Override
public void put(URI uri, Map<String, List<String>> arg1) throws IOException 
    Map<String, HttpCookie> cookies = parseCookies(arg1);
    Log.d("MyCookieHandler.put",
            "saving Cookies for domain: " + uri.getHost());

    addCookies(uri, cookies);
    Log.d("MyCookieHandler.put",
            "Cookie : " + TextUtils.join("; ", cookies.values()));
    Log.d("MyCookieHandler.put", "======");



private void addCookies(URI uri, Map<String, HttpCookie> cookies) 
    if (!cookies.isEmpty()) 
        if (urisMap.get(uri.getHost()) == null) 
            urisMap.put(uri.getHost(), cookies);
         else 
            urisMap.get(uri.getHost()).putAll(cookies);
        
        saveCookies();
    


private void saveCookies() 
    try 
        FileOutputStream fos = context.openFileOutput(COOKIE_FILE,
                Context.MODE_PRIVATE);

        JSONObject jsonuris = new JSONObject();
        for (Entry<String, Map<String, HttpCookie>> uris : urisMap
                .entrySet()) 
            JSONObject jsoncookies = new JSONObject();
            for (Entry<String, HttpCookie> savedCookies : uris.getValue()
                    .entrySet()) 
                jsoncookies.put(savedCookies.getKey(),
                        cookieToJson(savedCookies.getValue()));
            
            jsonuris.put(uris.getKey(), jsoncookies);
        
        fos.write(jsonuris.toString().getBytes());
        fos.close();
        Log.d("MyCookieHandler.addCookies", jsonuris.toString());
     catch (Exception e) 
        e.printStackTrace();
    


private static JSONObject cookieToJson(HttpCookie cookie) 
    JSONObject jsoncookie = new JSONObject();
    try 
        jsoncookie.put("discard", cookie.getDiscard());
        jsoncookie.put("maxAge", cookie.getMaxAge());
        jsoncookie.put("secure", cookie.getSecure());
        jsoncookie.put("version", cookie.getVersion());
        jsoncookie.put("comment", cookie.getComment());
        jsoncookie.put("commentURL", cookie.getCommentURL());
        jsoncookie.put("domain", cookie.getDomain());
        jsoncookie.put("name", cookie.getName());
        jsoncookie.put("path", cookie.getPath());
        jsoncookie.put("portlist", cookie.getPortlist());
        jsoncookie.put("value", cookie.getValue());

     catch (JSONException e) 

        e.printStackTrace();
    

    return jsoncookie;


private static HttpCookie jsonToCookie(JSONObject jsonObject) 
    HttpCookie httpCookie;
    try 
        httpCookie = new HttpCookie(jsonObject.getString("name"),
                jsonObject.getString("value"));
        if (jsonObject.has("comment"))
            httpCookie.setComment(jsonObject.getString("comment"));
        if (jsonObject.has("commentURL"))
            httpCookie.setCommentURL(jsonObject.getString("commentURL"));
        if (jsonObject.has("discard"))
            httpCookie.setDiscard(jsonObject.getBoolean("discard"));
        if (jsonObject.has("domain"))
            httpCookie.setDomain(jsonObject.getString("domain"));
        if (jsonObject.has("maxAge"))
            httpCookie.setMaxAge(jsonObject.getLong("maxAge"));
        if (jsonObject.has("path"))
            httpCookie.setPath(jsonObject.getString("path"));
        if (jsonObject.has("portlist"))
            httpCookie.setPortlist(jsonObject.getString("portlist"));
        if (jsonObject.has("secure"))
            httpCookie.setSecure(jsonObject.getBoolean("secure"));
        if (jsonObject.has("version"))
            httpCookie.setVersion(jsonObject.getInt("version"));
        return httpCookie;
     catch (JSONException e) 

        e.printStackTrace();
    
    return null;



private Map<String, HttpCookie> parseCookies(Map<String, List<String>> map) 
    Map<String, HttpCookie> response = new HashMap<String, HttpCookie>();

    for (Entry<String, List<String>> e : map.entrySet()) 
        String key = e.getKey();
        if (key != null
                && (key.equalsIgnoreCase(VERSION_ONE_HEADER) || key
                        .equalsIgnoreCase(VERSION_ZERO_HEADER))) 
            for (String cookie : e.getValue()) 
                try 
                    for (HttpCookie htpc : HttpCookie.parse(cookie)) 
                        response.put(htpc.getName(), htpc);
                    
                 catch (Exception e1) 

                    Log.e("MyCookieHandler.parseCookies",
                            "Error parsing cookies", e1);
                
            

        
    
    return response;



此答案尚未经过彻底测试。我使用 JSON 序列化 Cookie,因为那个类没有实现 Serializable,它是最终的。

【讨论】:

【参考方案11】:

在我的项目中,CookieManager 被解析为android.webkit.CookieManager。 我必须像下面这样设置处理程序以使 Volley 自动处理 cookie。

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

【讨论】:

以上是关于在 Android volley 库中使用 cookie的主要内容,如果未能解决你的问题,请参考以下文章

无法通过使用 Volley 库中的 Intent 从片段中移动下一个 Activity

Activity 在使用 volley 时泄漏了窗口

在 Android 上使用 Volley 获取 SSLHandshakeException

我一直在 android studio 中制作一个 News API 项目,但是 volley 出错了。错误 - com.android.volley.AuthFailureError。使用 json

Android Volley框架的使用

反应原生找不到 com.android.volley:volley:1.1.1