feresr feresr - 1 month ago 8
Android Question

Retrofit keeps forgeting my cookies :( Android

So, when I Log in into my server side application it gives me a cookie that allows me to say "Hey, it's me again" on future requests. I used to do this using Android's default HttpClient classes and it worked great. But I've been told that Retrofit is much faster and it spares you from handling JSON parsing by implementing GSON so I thought I'd give it a try.

I built my client and I can make requests, however, my client doesnt' remember the session key and thus I cannot do anything. Does anyone know how to tell retrofit "accept and user cookies for future requests"? I'm at a lost here! any suggestion will do :)

public class ApiClient{

private static final String API_URL = "http://192.168.1.25:8080";

private static RestAppApiInterface sRestAppService;

public static RestAppApiInterface getRestAppApiClient() {
if (sRestAppService == null) {

CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);

RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(API_URL)
.build();
sRestAppService = restAdapter.create(RestAppApiInterface.class);
}
return sRestAppService;
}

}

Answer

You need to set a Cookie persistent Client. Since you're using Android and retrofit I suggest using OKHttp wich is better supported by retrofit and Android thread safe, the way to this is the following

//First create a new okhttpClient (this is okhttpnative)
OkHttpClient client = new OkHttpClient(); //create OKHTTPClient
//create a cookieManager so your client can be cookie persistant
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager); //finally set the cookie handler on client

//OkClient is retrofit default client, ofcourse since is based on OkHttClient
//you can decorate your existing okhttpclient with retrofit's okClient
OkClient serviceClient = new OkClient(client);

//finally set in your adapter
RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("Some eNdpoint")
            .setClient(serviceClient)
            .build();

The point of using Okhttp instead of the defaultHttpClient(by apache) is that okhttp is threadsafe for android and better supported by retrofit.

Remembar that if you create another adapter you will need to set the same client, perhaps if you implement singleton on the client instance you will use the same one for all your requests, keeping in the same context

I hope this helps,best

Comments