相关疑难解决方法(0)

使用 Retrofit Android 对多个 API 进行常见成功/失败/错误处理的良好设计

我想以这样一种方式设计 API 调用,以便从一个地方轻松处理成功和失败响应(而不是为所有 API 编写相同的调用函数代码)

以下是我想考虑的场景。

  1. 在一个中心位置处理所有 API 的成功/失败和错误响应,如 4xx、5xx 等。
  2. 想要取消入队请求,并且如果请求已经发送,则在注销的情况下也停止处理响应(因为响应解析会修改应用程序的一些全局数据)
  3. 如果访问令牌已过期并且从云收到 401 响应,它应该获取新令牌,然后使用新令牌自动再次调用 API。

我目前的实现不满足上述要求。有没有办法使用 Retrofit 实现满足上述要求的 API 调用?请为我推荐一个好的设计。

这是我目前的实现:

  1. ApiInterface.java - 它是一个包含不同 API 调用定义的接口。
  2. ApiClient.java - 获取改造客户端对象以调用 API。
  3. ApiManager.java - 它具有调用 API 并解析其响应的方法。

接口接口.java

public interface ApiInterface {

    // Get Devices
    @GET("https://example-base-url.com" + "/devices")
    Call<ResponseBody> getDevices(@Header("Authorization) String token);

    // Other APIs......
}
Run Code Online (Sandbox Code Playgroud)

客户端程序

public class ApiClient {
    
    private static Retrofit retrofitClient = null;
    
    static Retrofit getClient(Context context) {

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .sslSocketFactory(sslContext.getSocketFactory(), systemDefaultTrustManager())
                    .connectTimeout(15, TimeUnit.SECONDS) …
Run Code Online (Sandbox Code Playgroud)

architecture performance android design-patterns retrofit

5
推荐指数
1
解决办法
579
查看次数

在 Android Retrofit 中并行调用多个 API 时,身份验证器刷新令牌

我想在访问令牌过期时刷新它。我已经实现了 Authenticator,如下所示:

@Singleton
class TokenAuthenticator(
    val authService: Lazy<AuthService>,
    private val sharedPreferences: SharedPreferences
) : Authenticator {


override fun authenticate(route: Route?, response: Response): Request? {
    return authRequestWithNewToken(response.request)
}

private fun authRequestWithNewToken(
    request: Request
): Request? {
    getFreshAccessToken()?.let { freshToken ->
        return getNewRequest(request, freshToken)
    }
    return null
}

private fun getFreshAccessToken(): String? {
    val refreshResponse = authService.get().refreshTokenTemp().execute()
    if (refreshResponse.isSuccessful) {
        val updatedAccessToken =
            refreshResponse.body()?.data?.accessToken ?: return null
        val updatedRefreshToken =
            refreshResponse.body()?.data?.refreshToken ?: return null
        updateToken(updatedAccessToken, updatedRefreshToken)
        Timber.tag("TOKEN")
            .d("Auth Updated token\n AccessToken: $updatedAccessToken …
Run Code Online (Sandbox Code Playgroud)

android android-authenticator retrofit okhttp refresh-token

5
推荐指数
1
解决办法
604
查看次数

为什么不调用改造 Authenticator?

我想将响应从服务器更改为 423 -> 401,然后使用 Authenticator 调用 refreshToken。

如果响应代码为 401,则调用该方法

但是为什么 在我的情况下不调用该方法Authenticator.authenticate(Route route, Response response)

OkHttp客户端

OkHttpClient httpClient = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    //Adding token to request
                    Request request = chain.request();
                    Request.Builder builder = request.newBuilder();
                    builder.header("Authorization", "access_token");
                    return chain.proceed(builder.build());
                }
            })
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    //changing response code from server 423 -> 401
                    Request request = …
Run Code Online (Sandbox Code Playgroud)

java authentication android retrofit retrofit2

3
推荐指数
1
解决办法
2389
查看次数

检查访问令牌是否过期

我有一个api,在验证后返回此信息

"token_type":"Bearer",
"expires_in":86400,
"access_token":"XXXXXXXXX",
"refresh_token":"XXXXXXXXXXX"
Run Code Online (Sandbox Code Playgroud)

我已经成功地在sqlite数据库中保存了访问令牌,刷新令牌和expires_in.如何检查令牌是否已过期?这是我到目前为止所拥有的

if(new Date().after(expiresAt)){
            Toast.makeText(this, "Token expired", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(this, "You still have time", Toast.LENGTH_SHORT).show();
        }
Run Code Online (Sandbox Code Playgroud)

expiresAt包含expires_in值

android

1
推荐指数
1
解决办法
3684
查看次数