18

我需要知道如何在改造中添加授权 cookie 标头。我已经看到了使用请求拦截器等的建议。下面是我正在尝试的,但这是正确的吗?首先,我已经需要一个 RequestAdatper 来第一次获取会话 ID。这只能由请求适配器的构建器设置。但我首先需要提出一个请求来获取会话 ID。我是否需要两个休息适配器,一个来获取 sessionId,另一个在我获得它之后。我真正需要的是适配器上的一种方法来设置cookie,但它似乎不是这样的方法。这越来越尴尬了。如何在改造中设置授权 cookie?我在常见问题解答或教程中没有看到这一点。

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 ???
4

5 回答 5

27

Keep a reference to the interceptor and treat it as a singleton like you would be RestAdapter itself.

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(...);
    }
  }
}

Now, simply call setSessionId after your authentication call. All subsequent requests will include the header.

于 2014-01-21T06:14:47.300 回答
12

你可以像这样得到cookies

 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);
于 2014-03-28T11:55:56.513 回答
8

步骤 1. 解析响应标头。 在覆盖方法中的回调中调用此success方法。

    /**
     * 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);
    }
}
于 2014-08-26T13:46:39.940 回答
5

根据@sbtgE 的回答,但有一些更正。CookieHandler.getDefault()可能为空,所以我使用 CookieManager。

应用程序的 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);
于 2016-08-22T13:07:22.570 回答
0

使用 lib 的简单解决方案。编译com.squareup.okhttp3:okhttp-urlconnection:3.2.0

JavaNetCookieJar jncj = new JavaNetCookieJar(CookieHandler.getDefault()); OkHttpClient.Builder().cookieJar(jncj).build();

于 2016-06-04T17:47:52.797 回答