有沒有一種方法可以在 okhttp3 攔截器中等待刷新的令牌?
最近,我不得不與一個(gè)使用Retrofit 1,okhttp3,jobManager和Picasso 2.71828的大型舊項(xiàng)目合作。應(yīng)用程序從服務(wù)器接收數(shù)據(jù)。交互邏輯:用戶登錄,接收令牌,刷新令牌。它們存儲(chǔ)在與 shHelper 的共享首選項(xiàng)中。使用令牌,他可以發(fā)送請(qǐng)求(他在URL中的某個(gè)位置,以及正文中的某個(gè)位置),借助刷新令牌,用戶可以在會(huì)話重置或令牌損壞時(shí)獲得新令牌。授權(quán)錯(cuò)誤(401)由okhttp3身份驗(yàn)證器處理,我們?cè)O(shè)法將其與畢加索一起使用。但是有一個(gè)問(wèn)題 - 畢加索如果屏幕上有幾張圖片 - 連續(xù)發(fā)送多個(gè)請(qǐng)求,同時(shí)或幾乎同時(shí),并且由于它們都立即收到答案401,如果令牌腐爛,身份驗(yàn)證器立即發(fā)送相同數(shù)量的更新令牌的請(qǐng)求。有沒有一些優(yōu)雅的方法來(lái)等待令牌更新,然后重復(fù)對(duì)其余圖片的請(qǐng)求?現(xiàn)在它發(fā)生如下 - 收到錯(cuò)誤401后,令牌重置為零(令牌= “”),并且落入身份驗(yàn)證器檢查的所有其他流是否(令牌==“”)執(zhí)行Thread.sleep()我對(duì)此非常不滿意private Authenticator getAuthenticator() { return (route, response) -> { if (errorCount > 3){ return null; } if (response.request().url().toString().endsWith("/refreshToken")) { Log.d(TAG, "getAuthenticator: " + "refreshToken"); PasswordRepeatActivity.start(context); return null; } if (response.request().url().toString().endsWith("/auth")) { String message = "Попробуйте позже"; try { com.google.gson.Gson gson = Gson.builder().create(); ApiResponse apiError = gson.fromJson(response.body().string(), ApiResponse.class); message = apiError.getMessage(); } catch (Exception e) { e.printStackTrace(); } throw new IOException(message); } String login = spHelper.getCurrentLogin(); Auth auth = spHelper.getAuth(login); String token = auth.getToken(); HttpUrl oldUrl = response.request().url();我正在尋找在第一個(gè)錯(cuò)誤401之后發(fā)送一個(gè)刷新令牌的請(qǐng)求并使用所有其他線程等待它的方法,然后使用新令牌發(fā)送請(qǐng)求。除了在身份驗(yàn)證器中等待更新的令牌之外,有沒有辦法以某種方式簡(jiǎn)化此代碼?現(xiàn)在這種方法大約有100行長(zhǎng),每次都需要更改它 - 甚至閱讀和保持頭腦中的邏輯也成為一個(gè)問(wèn)題。因此,經(jīng)過(guò)一段時(shí)間和一些嘗試,我使身份驗(yàn)證器的部分在某個(gè)鎖定對(duì)象上同步?,F(xiàn)在,一次只有一個(gè)線程可以訪問(wèn)身份驗(yàn)證器。因此,如果令牌需要刷新bs - 它將是,并且在刷新所有等待新令牌的線程后,將使用新令牌重復(fù)其調(diào)用。感謝@Yuri Schimke分享非常有用的信息。
查看完整描述