【发布时间】:2017-04-03 10:23:25
【问题描述】:
我有一个调用REST API 的安卓应用。 REST API 由JWT 保护,当用户登录应用程序时,我获得了 android 的令牌。令牌将在 60 分钟后过期。
在我的 android 应用程序中,我有不同的类,它们总共包含 50-60 个 REST 调用。 android 应用程序使用Retrofit 连接到这些 REST 方法。我有一些方法需要在执行另一个之后才能工作,这些方法在第一个方法的onResponse 方法中。
我编写了一个名为Token 的特殊类,其中set 和get 来自变量的JWT 令牌。每个 REST 调用都从此类获取令牌。
无论如何,由于 REST 使用 JWT 保护,我必须在 50 分钟后重新更新令牌。我首先要检查Token 类中的token 变量是否即将过期,它有一个特殊的方法whenWillExpire() 可以告诉我令牌何时过期。如果是,则再次调用 REST API 并获取新令牌。
情况是,因为我不知道在哪个 REST 调用上我必须重新更新令牌,所以我必须在 any REST 调用之前执行此令牌过期检查并在之前获取新令牌(如果过期)调用选定的 REST 方法。举个例子,假设我有一个名为 renew() 的方法,它检查令牌并通过执行 REST 工作从服务器获取它。 renew() 的执行完成后,任何其他 REST 调用都应该运行。 renew() 应该首先在每个 REST 调用请求上运行。这是此方法的一个示例。
private void renew(String token) {
if(token expired){
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(RestCommon.URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
GetNewToken endPoint = retrofit.create(GetNewToken.class);
Call<ResponseBody> call = endPoint.getNewToken();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
// Good. Now we have the token. Call other methods here.
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
}
else
{
//Not expired. Call other methods.
}
}
那么,在执行请求的方法之前,如何确保 renew() 在每个 REST 请求中运行?最好的设计是什么?我有 50-60 种 REST 方法,用不同的名称复制上面的代码并在其中添加其他 REST 调用绝对不是一个好的模式。
【问题讨论】:
-
这是一个明智的设计,我通常将所有 API 调用放在一个
interface中,并且我有一个类可以创建Retrofit retrofit ...的 1 个实例(单例)并在所有调用中使用它,并且,通常我创建一个类(包装器),该类在interface中为每个API 端点提供一个方法,在该方法中我调用使用retrofit实例来调用API,我将callback作为匿名内部类传递给方法,它可能看起来很复杂,如果你愿意,我可以发布一个答案。关键在于包装方法调用,你可以做所有你想做的检查,包括令牌过期、续订调用......等等 -
谢谢,请回复。但我也有“必须”一个接一个运行的 REST 调用。有时这个链有 6-7 个方法长。这也支持?
-
是的,您将在
onResponse()onFail()中将匿名内部类作为CallBack传递,您可以做任何您想做的事情。我会在几分钟内给你看一个样本 -
实际上我到了令牌需要刷新的时候,建议的设计支持这一点,但是一旦刷新令牌,就无法找到一种干净的方式来恢复原始请求,不确定您是否仍然感兴趣在答案中..?
-
@Yazan:实际上刷新的意思是生成一个新密钥。这只是另一个 REST 调用
标签: java android rest asynchronous retrofit