如何在请求正文中使用刷新令牌重试 rxjava 请求?

时间:2021-06-17 10:11:16

标签: android oauth-2.0 rx-java token refresh-token

该项目使用 OAuth2 协议。但是请求正文中有令牌,而不是标头。所以我找不到用新令牌再次发送请求的方法。 流程:请求 -> 失败 -> 刷新令牌 -> 请求

请求经验:
{“请求”:“asd”, "令牌":"...", “请求数据”:{} } 发生错误时,我使用相同的令牌发送相同的请求,如下所示:

requestExp().flatMap(resource -> {
          return Single.just(new Object());
    }).retryWhen(th-> {
        AtomicInteger counter = new AtomicInteger();
        return th.takeWhile(e -> {
            if (Objects.equals(e.getMessage(), "test")) {
                return counter.getAndIncrement() != 1;
            } 
        });
    });

有什么帮助吗?

1 个答案:

答案 0 :(得分:1)

你可以试试这样的:

    .retryWhen {
            return@retryWhen it.flatMapSingle { throwable ->
                if (throwable is HttpException && throwable.code() == 401) {
                    // when 401 error, let's update the token and retry after that
                    println("Invalid token")
                    return@flatMapSingle refreshToken() // token source will be updated
                }
                // other error, no retry
                return@flatMapSingle Single.error<Any>(throwable)
            }
        }

示例:

fun main() {
    class Params(val token: String)
    class Result

    val tokenSource = BehaviorSubject.create<String>()
    tokenSource.onNext("invalid_token")

    fun request(params: Params): Single<Result> {
        if (params.token != "valid_token") {
            val responseBody = "".toResponseBody("application/json".toMediaTypeOrNull())
            val response = retrofit2.Response.error<Any>(401, responseBody)
            return Single.error(HttpException(response))
        }
        return Single.just(Result())
    }

    fun refreshToken(): Single<String> {
        return Single.fromCallable {
            val token = "valid_token"
            tokenSource.onNext(token)
            return@fromCallable token
        }
    }  

    val s = tokenSource.firstOrError() // get latest token
            .flatMap { request(Params(it)) }
            .retryWhen {
                return@retryWhen it.flatMapSingle { throwable ->
                    if (throwable is HttpException && throwable.code() == 401) {
                        println("Invalid token")
                        return@flatMapSingle refreshToken() // token source will be updated
                    }
                    return@flatMapSingle Single.error<Any>(throwable)
                }
            }
            .subscribe(
                    {
                        println("Success")
                    },
                    {
                        println("Error $it")
                    }
            )

}

相关问题