当前位置: 首页 > 知识库问答 >
问题:

OkHttp和reverfit、refresh token与并发请求

宗建章
2023-03-14
public static <S> S createServiceAuthentication(Class<S> serviceClass, boolean hasPagination) {

        final String jwt = JWT.getJWTValue(); //Get jwt value from Realm

        if (hasPagination) {
            Gson gson = new GsonBuilder().
                    registerTypeAdapter(Pagination.class, new PaginationTypeAdapter()).create();

            builder =
                    new Retrofit.Builder()
                            .baseUrl(APIConstant.API_URL)
                            .addConverterFactory(GsonConverterFactory.create(gson));
        }

        OkHttpClient.Builder httpClient =
                new OkHttpClient.Builder();

        httpClient.addInterceptor(new AuthenticationInterceptor(jwt));
        httpClient.authenticator(new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) throws IOException {
                if (responseCount(response) >= 2) {
                    // If both the original call and the call with refreshed token failed,
                    // it will probably keep failing, so don't try again.
                    return null;
                }

                if (jwt.equals(response.request().header("Authorization"))) {
                    return null; // If we already failed with these credentials, don't retry.
                }

                APIRest apiRest = createService(APIRest.class, false);
                Call<JWTResponse> call = apiRest.refreshToken(new JWTBody(jwt));
                try {
                    retrofit2.Response<JWTResponse> refreshTokenResponse = call.execute();
                    if (refreshTokenResponse.isSuccessful()) {

                        JWT.storeJwt(refreshTokenResponse.body().getJwt());

                        return response.request().newBuilder()
                                .header(CONTENT_TYPE, APPLICATION_JSON)
                                .header(ACCEPT, APPLICATION)
                                .header(AUTHORIZATION, "Bearer " + refreshTokenResponse.body().getJwt())
                                .build();
                    } else {
                        return null;
                    }
                } catch (IOException e) {
                    return null;
                }
            }
        });

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

        return retrofit.create(serviceClass);
    }

    private static int responseCount(Response response) {
        int result = 1;
        while ((response = response.priorResponse()) != null) {
            result++;
        }
        return result;
    }

共有1个答案

戎俊
2023-03-14

如果我理解您的问题,一些请求是在令牌更新时发送的,这会给您一个错误。

您可以尝试在更新令牌时阻止所有请求(使用'synchronized'对象),但这将不包括已经发送的请求。

由于这个问题很难完全避免,也许正确的方法是有一个良好的后退行为。例如,通过使用更新后的令牌重新运行请求来处理在令牌更新期间发出请求时出现的错误。

 类似资料:
  • 我正试图优化这段代码以实现缓存的目的。此代码使缓存仅为1天之前,它重新连接到internet再次建立新的缓存。我想让它60天前,它再次访问网络,使新的缓存。此外,使用picasso对来自缓存的映像也会减慢picasso:2.5.2reverfit2:reverfit:2.7.2reverfit2:Converter-GSON:2.7.2OKHTTP3:OKHTTP:4.4.1OKHTTP3:Log

  • 我需要使50 http获取请求尽快与Android的改型。我正在使用OKHTTP的改型。目前,与普通Java和相比,Retrofit的工作做得很差:对于所有50个请求,如果我为设置池大小20,则为Retrofit设置50sec,为普通设置30sec,而为Retrofit/OkHttp设置。 如果查看logcat,我可以看到无论在中设置了什么,registfit最多执行5个并发请求,而在中,并发请求

  • OKHTTP在某种程度上支持并发请求API吗? 如果没有,最好的实现方法是什么?

  • 我的Java应用程序使用各种代理服务器从特定域收集数据。特别申请需要下列程序: 通过特定代理加载URL 等待5秒 通过同一个代理加载下一个url 为了使信息的加载(由于5秒的暂停)不需要永远,我总共使用400个线程。每个线程都使用自己的代理服务器,也就是使用自己的OKHTTP客户端: 每个线程必须使用自己的代理,因此每个线程都有自己的OKHTTP客户端。总共有400个OKHTTP客户端。 我做了一

  • 问题内容: 我读了一些将jsons发布到服务器的示例。 有人说: OkHttp是Java提供的HttpUrlConnection接口的实现。它提供用于编写​​内容的输入流,并且不知道(或不在乎)内容的格式。 现在,我想用名称和密码的参数对URL进行常规发布。 这意味着我需要自己将名称和值对编码为流? 问题答案: 当前接受的答案已过期。现在,如果您想创建一个发布请求并向其中添加参数,则应该使用Mul