我需要知道如何在改造中添加授权cookie标头。我已经看过使用请求截取等的建议。以下是我正在尝试的,但这是正确的吗?首先,我已经需要一个RequestAdatper来第一次获取会话ID。这只能由请求适配器的构建器设置。但我需要提出一个请求才能获得会话ID。我需要两个休息适配器,一个用于获取sessionId,另一个用于获取它之后。我真正需要的是一个适配器上的方法,在我得到它之后设置cookie,但它似乎不是这样的方法。这变得很尴尬。如何在改造中设置授权cookie?我在FAQ或教程中没有看到这一点。
RequestInterceptor requestInterceptor = new RequestInterceptor()
{
@Override
public void intercept(RequestFacade request) {
request.addHeader("Set-Cookie", "sessionId="+sessionIdentifier);
}
};
RestAdapter.Builder().setServer(serverURL)..setRequestIntercepter(requestIntercepter).build();
// but I don't have sessionId when this is first issued ???
答案 0 :(得分:27)
保留对拦截器的引用并将其视为单身,就像你自己RestAdapter
一样。
public class ApiHeaders implements RequestInterceptor {
private String sessionId;
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public void clearSessionId() {
sessionId = null;
}
@Override public void intercept(RequestFacade request) {
if (sessionId != null) {
request.setHeader(...);
}
}
}
现在,只需在身份验证通话后拨打setSessionId
即可。所有后续请求都将包含标题。
答案 1 :(得分:12)
您可以像这样获取Cookie
public class MyCookieManager extends CookieManager {
@Override
public void put(URI uri, Map<String, List<String>> stringListMap) throws IOException {
super.put(uri, stringListMap);
if (stringListMap != null && stringListMap.get("Set-Cookie") != null)
for (String string : stringListMap.get("Set-Cookie")) {
if (string.contains("JSESSIONID")) {
Preference.getInstance().setSessionId(string);
}
}
}
}
使用它来设置CookieHandler
MyCookieManager myCookieManager = new MyCookieManager();
CookieHandler.setDefault(myCookieManager);
然后在你的请求拦截器
中使用它 String sessionId = preference.getSessionId();
if (sessionId != null)
requestFacade.addHeader(Cookie, sessionId);
答案 2 :(得分:7)
步骤1.解析响应标头。
在覆盖success
方法的Callback中调用此方法。
/**
* Method extracts cookie string from headers
* @param response with headers
* @return cookie string if present or null
*/
private String getCookieString(Response response) {
for (Header header : response.getHeaders()) {
if (null!= header.getName() && header.getName().equals("Set-Cookie")) {
return header.getValue();
}
}
return null;
}
步骤2.编写一些静态类或单例以保留cookie和RequestInterceptor实例。在RequestInterceptor内部覆盖拦截方法,将您的cookie添加到Header。
public class RestAdapter {
private static String cookies;
public static String getCookies() {
return cookies;
}
public static void setCookies(String cookies) {
RestAdapter.cookies = cookies;
}
/**
* Injects cookies to every request
*/
private static final RequestInterceptor COOKIES_REQUEST_INTERCEPTOR = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
if (null != cookies && cookies.length() > 0) {
request.addHeader("Cookie", cookies);
}
}
};
public static final RestInterface getService() {
return new RestAdapter.Builder()
.setEndpoint(Config.ENDPOINT)
.setRequestInterceptor(COOKIES_REQUEST_INTERCEPTOR)
.setConverter(new JacksonConverter())
.setLogLevel(RestAdapter.LogLevel.NONE)
.build()
.create(RestInterface.class);
}
}
答案 3 :(得分:4)
根据@ sbtgE的回答,但有一些更正。 CookieHandler.getDefault()
可能为null,因此我使用CookieManager。
app的build.gradle:
dependencies {
...
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
}
设置改造:
service = new Retrofit.Builder()
.baseUrl(/* your base URL */)
.addConverterFactory(/* your favourite converter */)
.client(
new OkHttpClient.Builder()
// this line is the important one:
.cookieJar(new JavaNetCookieJar(new CookieManager()))
.build())
.build()
.create(YourInterface.class);
答案 4 :(得分:0)
使用lib的简单解决方案。编译com.squareup.okhttp3:okhttp-urlconnection:3.2.0
。
JavaNetCookieJar jncj = new JavaNetCookieJar(CookieHandler.getDefault());
OkHttpClient.Builder().cookieJar(jncj).build();