I need to add cookies with retrofit 2.0. If i understand correct, cookies - the same as headers. this cookies must be added:
private HashMap
First of all: cookie is not the same as a header. Cookie is a special HTTP header named Cookie followed by list of the pairs of keys and values (separated by ";"). Something like:
Cookie: sessionid=sessionid; token=token
Since you cannot set multiple Cookie headers in the same request you are not able to use two @Header annotations for separate values (sessionid and token in your sample). I can think of one very hacky workaround:
@GET("link")
Call<CbGet> getData(@Header("Cookie") String sessionIdAndToken);
You change your method to send sessionId and token in one string. So in this case you should manually generate cookie string beforehand. In your case sessionIdAndToken String object should be equal to "sessionid=here_goes_sessionid; token=here_goes_token"
The proper solution is to set cookies by adding OkHttp's (that is library Retrofit uses for making underlying http calls) request interceptor. You can see solution or adding custom headers here.
why not using the cookieJar option?
new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(
new OkHttpClient().newBuilder()
.cookieJar(new SessionCookieJar()).build())
.build();
private static class SessionCookieJar implements CookieJar {
private List<Cookie> cookies;
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
if (url.encodedPath().endsWith("login")) {
this.cookies = new ArrayList<>(cookies);
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
if (!url.encodedPath().endsWith("login") && cookies != null) {
return cookies;
}
return Collections.emptyList();
}
}
to add cookie header to okhttp request headers , add this in Interceptor:
request= request.newBuilder().addHeader("Cookie", sessionIdAndToken).build();
Ref:https://github.com/square/okhttp/wiki/Interceptors as mentioned by @Alexander Mironov
Full Example code here: Hope it helps you
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.List;
public class LoggingInterceptor implements Interceptor {
private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
request = processRequest(request);
logger.info("Sending request with url:{} and connection status:{} and request headers:{}",
request.url(), chain.connection(), request.headers());
Response response = chain.proceed(request);
long t2 = System.nanoTime();
logger.info("Received response for url:{} and time taken:{} and response headers as:{}",
response.request().url(), (t2 - t1) / 1e6d, response.headers());
response = processResponse(response);
return response;
}
//Add cookies for all subsequent requests
private Request processRequest(Request request) {
if(!request.url().toString().contains("/v1/authorize")) {
final EmployeeSession session = getSession();
StringBuilder etokenAndUId = new StringBuilder("etoken=");
etokenAndUId.append(session.getEtoken()).append(";").append("uId=").append(session.getUId());
logger.info("inside processRequest for all subsequent requests, sending cookies as etokenAndUId values:{}", etokenAndUId.toString());
request= request.newBuilder().addHeader("Cookie", etokenAndUId.toString()).build();
}
return request;
}
//Extract cookies from login url
private Response processResponse(Response response) {
if(response.request().url().toString().contains("/v1/authorize")) {
final List<String> cookieHeaders = response.headers("Set-Cookie");
String etoken = "", uId = "";
for (String cookieHeader : cookieHeaders) {
if(cookieHeader.contains("etoken=")) {
etoken = cookieHeader.substring(7, cookieHeader.indexOf(';'));
}
else if(cookieHeader.contains("uId=")) {
uId = cookieHeader.substring(4, cookieHeader.indexOf(';'));
}
}
logger.info("inside processResponse found cookies from login url response: etoken:{} and uid:{}", etoken, uId);
setSession(etoken, uId, "c1");
logger.info("current employee session:{}", getSession());
}
return response;
}
}
API web service example add Header
@FormUrlEncoded
@POST("getDriverRoutes")
Call<Guzergah> getGuzergah(@Header("Cookie") String userCookie, @Field("driver_id") int driver_id);
when you login to system save cookies to your local on Response like
public void onResponse(Response<Login> response, Retrofit retrofit) {
hidepDialog();
String cookie = response.headers().get("Set-Cookie");
editor.putString("user_cookie", cookie.split(";")[0]);
editor.commit();
and in every service you need to be autorised send your cookies , get from sharepreference and send it with your web service
String userCookie = shp.getString("user_cookie", ""); // here is cookies before send
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://server.aracadabra.com:8080/").
addConverterFactory(GsonConverterFactory.create())
.build();
final APIService service = retrofit.create(APIService.class);
final Call<SenMsgStatus> loginMCall = service.sendMessage(userCookie, type, route_id, user_id, passenger_id, passenger_status, text);