有时在API响应中,我得到 401 未授权状态码。 我试图在我的 网络拦截器,但仍然应用程序崩溃。不知道我做错了什么,希望能得到帮助。
以下是我的RetrofitFactory类
object RetrofitFactory {
private val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(
OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.addInterceptor(
object : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request: Request = chain.request()
.newBuilder()
.build()
return chain.proceed(request)
}
}
)
.addNetworkInterceptor(
Interceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
val request = requestBuilder.build()
val response = chain.proceed(request)
Log.e("request", request.headers.toString())
Log.e("Response Body", response.body!!.toString())
when (response.code) {
HttpURLConnection.HTTP_OK -> return@Interceptor response
HttpURLConnection.HTTP_UNAUTHORIZED -> sessionExpired(
BaseApplication.getApplication()
)
HttpURLConnection.HTTP_FORBIDDEN -> sessionExpired(
BaseApplication.getApplication()
)
}
response
}
)
.build()
)
.build()
@JvmStatic
fun <S> createService(serviceClass: Class<S>): S {
return retrofit.create(serviceClass)
}
}
我想把用户移动到登录界面。所以这里是应该被调用的函数,但没有调用。
fun sessionExpired(application: Application) {
val intent = Intent(application, LogInActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
application.startActivity(intent)
}
这里是我的依赖关系。
//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.7.2'
implementation 'com.squareup.retrofit2:converter-gson:2.7.2'
//logging interceptor
implementation "com.squareup.okhttp3:logging-interceptor:4.4.0"
我还看了 此处 以及许多其他类似的问题,但没有找到帮助!
更新一下我是如何调用API:
在viewmodel中用这个
viewModelScope.launch(Dispatchers.IO) {
val apiResponse = apiEndPointsInterface.loginUser(loginRequestModel)
returnLoginResponse(apiResponse)
}
而APIEndPointInterface是这样的。
@POST(AppConstants.APIEndPoints.LOGIN_USER)
suspend fun loginUser(
@Body requestLoginModel: LoginRequestModel
): LoginResponseModel
你应该在改造请求的onFailure方法中调用sessionExpired函数。
override fun onFailure(call: Call<Model.Result>, t: Throwable) {
if(t is HttpException && t.statusCode==401)
sessionExpired(BaseApplication.getApplication())
}
如果你使用的是Kotlin coroutines。你应该把 await 调用包在 try catch 块中,然后在 catch 块中调用函数。请看下面的代码。
val response: String
val getPlacesDeferred = PlaceAPI.retrofitService.getPlacesAsync()
response = getPlacesDeferred.await())
} catch (exception:Exception) {
if(exception is HttpException && t.statusCode==401)
sessionExpired(BaseApplication.getApplication())
}
为了解决这种问题,在进行任何api调用或使用retrofit时,你必须使用缓存策略。你必须使用缓存策略,使用Retrofit和Okhttp来解决你的问题。它还可以帮助你防止在调用api的过程中出现任何不必要的应用程序崩溃,即使你的应用程序没有连接到互联网。