Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/192.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 改装及保养;RxJava2刷新令牌并重试_Android_Kotlin_Rx Java2 - Fatal编程技术网

Android 改装及保养;RxJava2刷新令牌并重试

Android 改装及保养;RxJava2刷新令牌并重试,android,kotlin,rx-java2,Android,Kotlin,Rx Java2,我有一个登录端点,通过它我可以接收authToken和refreshToken。第一个将在一小时后过期,因此我应该使用第二个来刷新它并继续应用程序流 现在,我的应用程序到处都是改装呼叫,我可能在任何给定时刻都会收到401,那么我如何才能在每次收到401时都发出刷新令牌,然后重试原始请求 这是我的刷新签名: @POST("/auth/actions/refresh") fun refreshToken(@Body tokenRefresh: TokenRefresh): Single&l

我有一个登录端点,通过它我可以接收authToken和refreshToken。第一个将在一小时后过期,因此我应该使用第二个来刷新它并继续应用程序流

现在,我的应用程序到处都是改装呼叫,我可能在任何给定时刻都会收到
401
,那么我如何才能在每次收到
401
时都发出刷新令牌,然后重试原始请求

这是我的刷新签名:

 @POST("/auth/actions/refresh")
    fun refreshToken(@Body tokenRefresh: TokenRefresh): Single<LoginResponse>
fun reauthenticate(): Single<AnyAuthResponse>
@POST(“/auth/actions/refresh”)
fun refreshToken(@Body tokenRefresh:tokenRefresh):单个
我考虑用一个方法
withAuth()
创建一个基本存储库类,该方法将任何
可观察的
/
单个
/
可流动的
,然后应用这个逻辑,但我找不到实现它的方法

看到了很多实现,但没有一个符合我的需要。。。有人能把我推向正确的方向吗


但是,我发现flatmapping上似乎有一些错误,我只是遇到了类似的需求,并提出了以下解决方案。它非常简单,只需尝试调用REST端点一次,如果使用HTTP 401调用失败,它将重新验证并再次重复调用。否则它只会发出原始错误

fun <T> Single<T>.withAuth() = retryWhen { errors ->
    var firstAttempt = true
    errors.flatMapSingle { error ->
        if (firstAttempt && error is HttpException && error.code() == 401) {
            firstAttempt = false
            reauthenticate()
        } else {
            Single.error(it)
        }
    }
}
fun Single.withAuth()=retryWhen{errors->
var firsttrunt=true
errors.flatMapSingle{error->
if(firsttrunt&&error为HttpException&&error.code()==401){
首次尝试=错误
重新验证()
}否则{
单一错误(it)
}
}
}
其中,重新验证功能具有以下签名:

 @POST("/auth/actions/refresh")
    fun refreshToken(@Body tokenRefresh: TokenRefresh): Single<LoginResponse>
fun reauthenticate(): Single<AnyAuthResponse>
fun重新验证():单一

请注意,具体的异常类型可能取决于您实际使用的HTTP实现,因此您可能希望更新条件以检测HTTP 401响应,但代码应该为您提供解决问题的总体方案。

我认为您可以在不修改所有调用的情况下完成此操作。在改装中添加一个
验证器

您可以使用Interceptor拦截每个请求,并检查它是否返回
401
-未经授权的访问和iff,然后刷新令牌并重播当前API请求

public final class SessionInterceptor implements Interceptor {
  // gets intercept
  @Override public Response intercept(@NonNull final Chain chain) throws IOException {

   final Request request = chain.request();
   final Response response = chain.proceed(request);
   final ResponseBody responseBody = response.body();

   if (response.code() == 401) {
      synchronized (this) {
      // Refresh your token
      // Update your authToken + Refreshed token
      final retrofit2.Response response = refreshToken();
      }
   }

   // Replay the original request
   // Perform request, here original request will be executed
   final Request original = chain.request();
   final Request.Builder builder = original.newBuilder();

   // Set your new refreshed token
   if (accessToken.isSet()) {
     builder.header(AUTHORIZATION, String.format(BEARER, 
     accessToken.get()));
    }

    final Request request = builder.method(original.method(), original.body()).build();

    return chain.proceed(request);
 }
}