如何从响应改造中检索 cookie,okhttp?

Posted

技术标签:

【中文标题】如何从响应改造中检索 cookie,okhttp?【英文标题】:How to retrieve cookie from response retrofit, okhttp? 【发布时间】:2018-06-13 21:38:01 【问题描述】:

我正在尝试从 API 响应中检索 Cookie 值,以通过将 cookie 值设置为新的 API 调用来维护后端会话,以防 APP 关闭:

PostMan RestClient 对 API 调用的响应:

RetrofitClient.java

public static Retrofit getClient() 

    if (checkClient()) 
        return getRetrofit();
    

    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    CookieHandler cookieHandler = new CookieManager();

    okhttp3.OkHttpClient client = new okhttp3.OkHttpClient.Builder().addNetworkInterceptor(interceptor)
            .cookieJar(new JavaNetCookieJar(cookieHandler))
            .connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();

    Gson gson = new GsonBuilder()
            .setLenient()
            .create();

    retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(client)
            .build();
    return retrofit;

API 调用

private void userLogin(String username, String password) 
    Retrofit retrofit = RetrofitClient.getClient();

    final LoginServices loginServices = retrofit.create(LoginServices.class);
    Call<LoginResponse> call = loginServices.userLogin(username, password);

    call.enqueue(new Callback<LoginResponse>() 
        @Override
        public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) 
            Log.d("Response code:", "===========" + response.code());

            Log.d("==Cookie==1===", "==="+response.raw().request().headers().get("Cookie"));
            Log.d("==Cookie==2==", "==="+response.headers().get("Cookie"));
            Log.d("==Content-Type====", "==="+response.headers().get("Content-Type"));

        

        @Override
        public void onFailure(Call<LoginResponse> call, Throwable t) 
            Log.e("TAG", "=======onFailure: " + t.toString());
            t.printStackTrace();
            // Log error here since request failed
        
    );

Logcat:

Response code:: ===========200
==Cookie==1===: ===null
==Cookie==1===: ===null
==Content-Type====: ===application/json

我还尝试了其他各种对我不起作用的方法。请帮忙!

【问题讨论】:

response.raw().headers().get("Cookie") 试试这个 已经试过了,不行@ManthanPatel @AnuragDhunna,参考这个gist。 @whenthemorningcomes 不起作用:( 【参考方案1】:

试试response.headers().get("Set-Cookie"))

【讨论】:

这并不完全正确。使用 response.headers().values("Set-Cookie")) 获取所有 cookie,它返回一个 List 并且应该有你所有的 cookie【参考方案2】:
List<String> Cookielist = response.headers().values("Set-Cookie");
String jsessionid = (Cookielist .get(0).split(";"))[0];

这对我有用,不是完美的解决方案,但确实有效

【讨论】:

就我而言,我需要执行以下操作才能获得它。 List Cookielist = response.headers().values("Set-Cookie"); String jsessionid = (Cookielist.get(0).split(";"))[0].split("=")[1];【参考方案3】:

标题名称是“Set-Cookie”而不是“Cookie”

您采用的方法不正确。如果要保存 Cookie,可以创建一个拦截器,保存 Cookie,以后想用的时候再用。

这里要做的,首先创建一个拦截器

public class ReceivedCookiesInterceptor implements Interceptor 

PreferencesHelper preferencesHelper;

public ReceivedCookiesInterceptor(Context context) 
    FineractApplication.get(context).getComponent().inject(this);
    preferencesHelper = PreferencesHelper(context)


@Override
public Response intercept(Chain chain) throws IOException 
    Response originalResponse = chain.proceed(chain.request());

    if (!originalResponse.headers("Set-Cookie").isEmpty()) 
        HashSet<String> cookies = new HashSet<>();
        for (String header : originalResponse.headers("Set-Cookie")) 
            cookies.add(header);
        
        // Save the cookies (I saved in SharedPrefrence), you save whereever you want to save
        preferencesHelper.putStringSet(PreferenceKey.PREF_KEY_COOKIES, cookies);
    
    return originalResponse;
  

我们在这里保存您收到的所有 cookie 作为响应。

现在您有了 cookie,是时候使用它了。

无论您想在哪里使用,只需获取您之前保存的 cookie

 HashSet<String> cookies = (HashSet<String>) preferencesHelper.getStringSet(
                        PreferenceKey.PREF_KEY_COOKIES);
        if (cookies != null) 
            for (String cookie: cookies)   
                // Use this cookie whereever you wanna use.               
                Log.d("Cookie", cookie);                 
            
        

祝你好运?

【讨论】:

您好,我是从 Gist gist.github.com/nikhiljha/52d45ca69a8415c6990d2a63f61184ff 关注的,每次查询服务器时我都必须调用 AddCookieInterceptor 和 ReceiveCookieInterceptor 吗?示例:我有登录查询我将使用什么拦截器?然后我有第二个查询,比如获取一些数据,我将使用什么拦截器?请回复。谢谢

以上是关于如何从响应改造中检索 cookie,okhttp?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 OkHttp 在 Android 上实现 cookie 处理?

如何从 POST 请求中检索 cookie?

改造:如何从 okhttp 拦截器再次重试请求?

离线时可以使用 OKHttp 进行改造吗?

改造:来自 gson 转换体的原始响应体

无法从缓存 okHttp 和改造中加载数据