改造 - 后续请求过多:21

Retrofit - Too many follow-up requests: 21

我正在使用改造来提出请求。

我遇到以下错误:

java.net.ProtocolException: Too many follow-up requests: 21

代码如下:

private OkHttpClient httpClient;
private CookieManager cookieManager;

public <S> S createCookieService(Class<S> serviceClass) {
    httpClient.interceptors().clear();
    httpClient.setCookieHandler(cookieManager);
    Retrofit.Builder builder = new Retrofit
            .Builder()
            .client(httpClient)
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create());

    Retrofit retrofit = builder.client(httpClient).build();

    return retrofit.create(serviceClass);
}

然后我提出要求:

示例:

1) 登录

 @POST("/login")
 Call<User> login();

2) 一些请求:

@GET("/request")
Call<PojoPojo> getPojo();

我收到此错误的后续请求太多:21.

请帮忙。

杰克沃顿写道:

This gets thrown (by OkHttp, not Retrofit) when there are more than 20 redirects when calling an endpoint. Usually this indicates a redirect cycle between two endpoints. Both Chrome and Firefox will also stop loading the request after this many redirects and fail the request.

You need to consult with your server team or endpoint documentation to ensure you are passing the correct data directly to the endpoint you want to call. No action for Retrofit to take here.

线程的其余部分在那里: https://github.com/square/retrofit/issues/1561

对我来说,问题是:请求 url 以 "/" 开头。
将 url @GET("/request") 替换为 @GET("request")

  • api 的基数 url 也应以 "/"
  • 结尾
  • 如果使用 Authorization header 检查是否需要将值设置为 "Bearer " + token 而不是

使用改造 2.4.0 版本:

<dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>retrofit</artifactId>
    <version>2.4.0</version>
</dependency>

作为解决方法,可以使用:

new OkHttpClient.Builder() .followRedirects(FALSE) .followSslRedirects(FALSE)

很高兴看看 okhttp3.internal.http.RetryAndFollowUpInterceptor class 源代码。

我使用的是 OkHttp 3.12.0 版本。

当令牌的 header 的密钥已经存在并且没有用新令牌替换它时也会发生这种情况,如下所示:

response.request.newBuilder()
                .header("Authorization", token)
                .build()

你添加新的令牌(一个键可以在 header 中有很多值),在很多问题中常见的是像这样添加令牌:

response.request.newBuilder()
                .addHeader("Authorization", token)
                .build()

这将导致请求再次失败 (401),您将陷入循环。

TL;DR: 设置新令牌的正确方法是:

response.request.newBuilder()
                    .header("Authorization", token)
                    .build()

In my case it was happening because of the cookie in header was expired. It is clear that we need to fix this in server side code but in case we can't change server side code we can use this workaround.

以下是对我有用的解决方法

catch (ProtocolException e) {
        
        Timber.w(e);
        if (e.getMessage().contains("Too many follow-up requests")) {
            doSynchronousLogin();

            Request.Builder builder = chain.request().newBuilder();
            builder.addHeader("Cookie", dataManager.getCookie());
            Timber.w("Request processed after auto-login");
            return chain.proceed(builder.build());
        }
    }

以上代码是在改造拦截器中添加的