【问题标题】:Set custom cookie in Retrofit在 Retrofit 中设置自定义 cookie
【发布时间】:2014-02-27 02:42:54
【问题描述】:

有没有办法在改造请求上设置自定义 cookie?

使用RequestInterceptor 或任何其他方式?

【问题讨论】:

    标签: android retrofit


    【解决方案1】:

    通过retrofit.RequestInterceptor

    @Override
    public void intercept(RequestFacade request) {    
         request.addHeader("Cookie", "cookiename=cookievalue");
    }
    

    您可以设置自定义RequestInterceptor,如下所示:

    String cookieKey = ...
    String cookieValue = ...
    
    RestAdapter adapter = new RestAdapter.Builder()
        .setRequestInterceptor(new RequestInterceptor() {
          @Override
          public void intercept(RequestFacade request) {
            // assuming `cookieKey` and `cookieValue` are not null 
            request.addHeader("Cookie", cookieKey + "=" + cookieValue);
          }
        })
        .setServer("http://...")
        .build();
    
    YourService service = adapter.create(YourService.class);
    

    要读取服务器设置的任何 cookie,请附加一个自定义 cookie 管理器,如下所示:

    OkHttpClient client = new OkHttpClient();
    CustomCookieManager manager = new CustomCookieManager();
    client.setCookieHandler(manager);
    
    RestAdapter adapter = new RestAdapter.Builder()
        .setClient(new OkClient(client))
        ...
        .build();
    

    CustomCookieManager 可能如下所示:

    public class CustomCookieManager extends CookieManager {
    
      // The cookie key we're interested in.    
      private final String SESSION_KEY = "session-key";
    
      /**
       * Creates a new instance of this cookie manager accepting all cookies.
       */
      public CustomCookieManager() {
        super.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
      }
    
      @Override
      public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException {
    
        super.put(uri, responseHeaders);
    
        if (responseHeaders == null || responseHeaders.get(Constants.SET_COOKIE_KEY) == null) {
          // No cookies in this response, simply return from this method.
          return;
        }
    
        // Yes, we've found cookies, inspect them for the key we're looking for.
        for (String possibleSessionCookieValues : responseHeaders.get(Constants.SET_COOKIE_KEY)) {
    
          if (possibleSessionCookieValues != null) {
    
            for (String possibleSessionCookie : possibleSessionCookieValues.split(";")) {
    
              if (possibleSessionCookie.startsWith(SESSION_KEY) && possibleSessionCookie.contains("=")) {
    
                // We can safely get the index 1 of the array: we know it contains
                // a '=' meaning it has at least 2 values after splitting.
                String session = possibleSessionCookie.split("=")[1];
    
                // store `session` somewhere
    
                return;
              }
            }
          }
        }
      }
    }
    

    【讨论】:

    • 您在哪里准确地添加了此代码,您还需要执行其他操作吗?另外,cookiename=cookievalue 中的内容是什么?
    • @Eric:你是如何从响应中获取cookie值的?
    • 我想知道同样的事情
    • @David Constants.SET_COOKIE_KEY 是什么?
    • @David 如何将 cookie 添加到CookieManager 中的sharedPreferences
    【解决方案2】:

    retrofit2就是这样处理的

    Gradle:

    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    

    代码:

    static final class CookieInterceptor implements Interceptor {
                private volatile String cookie;
    
                public void setSessionCookie(String cookie) {
                    this.cookie = cookie;
                }
    
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    if (this.cookie != null) {
                        request = request.newBuilder()
                                .header("Cookie", this.cookie)
                                .build();
                    }
                    return chain.proceed(request);
                }
    }
    
    
    class Creator {
    
        public static MyApi newApi() {
            Gson gson = new GsonBuilder()
                    .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
                    .create();
    
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .addInterceptor(new CookieInterceptor())
                    .build();
    
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(MyApi.URL)
                    .callFactory(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();
            return retrofit.create(MyApi.class);
        }
    }
    

    【讨论】:

      【解决方案3】:

      另一种设置cookie的方法是这样的:

      @Headers("Cookie: cookiename=cookievalue")
      @GET("widget/list")
      Call<List<Widget>> widgetList();
      

      这是一种动态方式:

      @GET("user")
      Call<User> getUser(@Header("Cookie") String cookie)
      

      【讨论】:

        【解决方案4】:

        我才刚刚开始使用 RetroFit,但它处理 cookie 的方式似乎与图书馆的其他部分不相上下。我最终做了这样的事情:

        // Set up system-wide CookieHandler to capture all cookies sent from server.
        final CookieManager cookieManager = new CookieManager();
        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
        CookieHandler.setDefault(cookieManager);
        
        // Set up interceptor to include cookie value in the header.
        RequestInterceptor interceptor = new RequestInterceptor() {
          @Override
          public void intercept(RequestFacade request) {
            for (HttpCookie cookie : cookieManager.getCookieStore().getCookies()) {
              // Set up expiration in format desired by cookies
              // (arbitrarily one hour from now).
              Date expiration = new Date(System.currentTimeMillis() + 60 * 60 * 1000);
              String expires = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz")
                  .format(expiration);
        
              String cookieValue = cookie.getName() + "=" + cookie.getValue() + "; " +
                  "path=" + cookie.getPath() + "; " +
                  "domain=" + cookie.getDomain() + ";" +
                  "expires=" + expires;
        
              request.addHeader("Cookie", cookieValue);
            }
          }
        };
        
        RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("https://api.github.com")
            .setRequestInterceptor(interceptor) // Set the interceptor
            .build();
        
        GitHubService service = restAdapter.create(GitHubService.class);
        

        【讨论】:

        • 我绝对同意你的说法,即 cookie 处理低于标准。
        猜你喜欢
        • 2011-04-22
        • 1970-01-01
        • 2016-06-13
        • 1970-01-01
        • 2021-07-14
        • 1970-01-01
        • 2014-12-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多