wake-up-neo.com

Setzen Sie in Retrofit ein benutzerdefiniertes Cookie

Gibt es eine Möglichkeit, bei Nachrüstungsanfragen ein benutzerdefiniertes Cookie zu setzen?

Entweder mit der RequestInterceptor oder mit anderen Mitteln?

17
David

Durch den retrofit.RequestInterceptor:

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

Sie können eine benutzerdefinierte RequestInterceptor wie folgt festlegen:

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

Fügen Sie einen benutzerdefinierten Cookie-Manager wie folgt hinzu, um alle vom Server gesetzten Cookies zu lesen:

OkHttpClient client = new OkHttpClient();
CustomCookieManager manager = new CustomCookieManager();
client.setCookieHandler(manager);

RestAdapter adapter = new RestAdapter.Builder()
    .setClient(new OkClient(client))
    ...
    .build();

wo CustomCookieManager so aussehen könnte:

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

So wird's gemacht für retrofit2

Gradle:

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

Der Code:

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);
    }
}
2
arsent

Eine andere Möglichkeit, ein Cookie zu setzen, ist die folgende:

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

Und hier ist ein dynamischer Weg:

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

Ich habe gerade erst mit RetroFit angefangen, aber die Art und Weise, wie Cookies behandelt werden, scheint nicht mit dem Rest der Bibliothek mitzuhalten. Ich habe so etwas gemacht:

// 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);
0
Tremelune