问题 你如何防止Retrofit自动跟随302


我有一个身份验证调用,我正在尝试使用Android上的Retrofit。该调用将302返回到成功或失败页面。原始302响应会返回维护身份验证成功所需的会话cookie,但是在我有机会使用cookie之前,Retrofit会自动将请求移交给重定向URL。

有没有办法阻止重定向?或者有没有办法在Retrofit上编写响应处理程序,可以在进行第二次调用之前添加适当的标头?


4494
2018-06-09 19:36


起源



答案:


为了防止您必须配置客户端的重定向,例如OkHttp 2:

private sendRequest() {
    OkHttpClient client = new OkHttpClient();
    client.setFollowRedirects(false);

    connectAdapter = new RestAdapter.Builder()
            .setClient(new OkClient(client))
            .setEndpoint("http://yourendpoint")
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();

    connectAdapter.create(YourRequest.class).sendMyRequest("login","password");

}

使用OKHTTP 3(您可以阅读此内容 回答 来自@gropapa):

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.followRedirects(false);
OkHttpClient httpClient = builder.build();

6
2018-03-22 15:05



这导致改造抛出错误,而不是返回具有303的响应。这是预期的行为吗? - android_student
我不知道,在我的情况下,问题是在302之上发生的重定向。没有抛出错误。在您的情况下改装会出现什么样的错误? - Climbatize
嘿,我不知道它是否仍然相关,但你可以添加一个try catch arround并从异常中读取响应。播种,直到有其他方式不遵循重定向,但仍然读取响应,你可以使用try catch。 - Dominik


答案:


为了防止您必须配置客户端的重定向,例如OkHttp 2:

private sendRequest() {
    OkHttpClient client = new OkHttpClient();
    client.setFollowRedirects(false);

    connectAdapter = new RestAdapter.Builder()
            .setClient(new OkClient(client))
            .setEndpoint("http://yourendpoint")
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();

    connectAdapter.create(YourRequest.class).sendMyRequest("login","password");

}

使用OKHTTP 3(您可以阅读此内容 回答 来自@gropapa):

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.followRedirects(false);
OkHttpClient httpClient = builder.build();

6
2018-03-22 15:05



这导致改造抛出错误,而不是返回具有303的响应。这是预期的行为吗? - android_student
我不知道,在我的情况下,问题是在302之上发生的重定向。没有抛出错误。在您的情况下改装会出现什么样的错误? - Climbatize
嘿,我不知道它是否仍然相关,但你可以添加一个try catch arround并从异常中读取响应。播种,直到有其他方式不遵循重定向,但仍然读取响应,你可以使用try catch。 - Dominik


我知道这是一个很老的帖子,也许它对某些人来说仍然有用。 我有类似的问题,我的解决方案是添加redirectStrategy(http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/RedirectStrategy.html)到httpClient:

private static final RestAdapter REST_ADAPTER= new RestAdapter.Builder()
            .setEndpoint(HTTP_TEST_URL)
            .setClient(new ApacheClient(HttpClients.custom()
                .setRedirectStrategy(new RedirectStrategy() {
                    @Override
                    public boolean isRedirected(HttpRequest request, HttpResponse response,
                        HttpContext context) throws ProtocolException {
                        return response.getStatusLine().getStatusCode() == 302;
                    }

                    @Override
                    public HttpUriRequest getRedirect(HttpRequest request,
                        HttpResponse response, HttpContext context)
                        throws ProtocolException {

                        //String cookieValue = response.getFirstHeader("Set-Cookie").getValue();
                        String location = response.getFirstHeader("location").getValue();

                        HttpUriRequest request_= new HttpGet(location);
                        return request_;
                    }}).build()))
            .build();

有了这个,我可以访问任何(私人)网址。我认为cookie数据会自动添加。也许你应该重写getRedirect(),isRedirected()函数来传递你的特殊需求。


2
2018-03-19 09:52



并记住为您的应用添加正确的依赖: hc.apache.org/httpcomponents-client-4.3.x/android-port.html。 - Marian Paździoch


事件如果帖子非常陈旧,这是我的答案与OkHttp 3 只需使用构建器,如下所示

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.followRedirects(false);
OkHttpClient httpClient = builder.build();

在Response对象中(我实际使用Retrofit),您将找到重定向URL

response.headers.get("Location")

希望这可以帮助


2
2018-02-02 22:45





我和你的情况类似。基本上我们需要的是捕获服务器在重定向之前返回的“Set-Cookie”标头。这是我使用OkHTTP处理它的方式:

final OkHttpClient client = new OkHttpClient();
CookieHandler handler = client.getCookieHandler();
CookieManager manager = new CookieManager();
handler.setDefault(manager);

//boilerplate:
RequestBody formData = new FormEncodingBuilder()
        .add("req_username", username)
        .add("req_password", password).build();
Request request = new Request.Builder().url(LOGIN_URL).post(formData).build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

// print our cookies:
List <HttpCookie> cookies = manager.getCookieStore().getCookies();
for(HttpCookie cookie : cookies) {
    Log.v(TAG, cookie.getName() + "=" + cookie.getValue());
}

0
2018-06-12 14:36





我已经编辑了我以前的答案,因为你最有可能在调用登录休息api时使用POST / PUT,而OkHttp在重定向之前将任何非GET或HEAD请求转换为GET请求,这可能对你不起作用。

目前,OkHttp缺少禁用重定向的功能,但我已经提交了拉取请求。如果该拉取请求被接受,它应该允许您禁用重定向,让您有机会暂时自行处理此用例。

这是拉取请求 https://github.com/square/okhttp/pull/944


0
2018-06-17 15:21