Retrofit 2.0 - 添加 header 不起作用
Retrofit 2.0 - Adding header does not work
我正在开发一个 Android 应用程序,我想在其中使用 Retrofit
调用一个 API。 API 需要 header 中的授权令牌,我也添加了相同的内容。
下面是代码片段
RetrofitClient.kt
object RetrofitClient {
var apiInterface: APIInterface? = null
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(300, TimeUnit.SECONDS)
.writeTimeout(300, TimeUnit.SECONDS)
.readTimeout(180, TimeUnit.SECONDS)
@Synchronized
fun getClient(context: Context): APIInterface {
if (apiInterface == null) {
if (SharedPreference.isAuthTokenExists(context))
okHttpClient.addInterceptor(HeaderInterceptor(context))
apiInterface =
Retrofit.Builder()
.baseUrl(context.resources.getString(R.string.base_url))
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient.build())
.build().create<APIInterface>(APIInterface::class.java)
}
return apiInterface as APIInterface
}
}
HeaderInterceptor.kt
class HeaderInterceptor(private val context: Context) : Interceptor {
private val HEADER_TOKEN = "token"
override fun intercept(chain: Interceptor.Chain): Response = chain.run {
proceed(
request()
.newBuilder()
.addHeader(
HEADER_TOKEN, "Bearer " + SharedPreference.initialize(context).getString(
Extras.AUTH_TOKEN, ""
)
).build()
)
}
}
APIInterface.kt
interface APIInterface {
@POST("dialtogo/otp/verification")
fun submitOTP(@Body otpModel: OTPModel): Call<ResponseFormat.GenericResponse?>?
}
OTPRepository.kt
class OTPRepository(private var ctx: Context) {
fun submitOTP(otpModel: OTPModel) {
val apiInterface: APIInterface = RetrofitClient.getClient(ctx)
val call: Call<ResponseFormat.GenericResponse?>? = apiInterface
.submitOTP(otpModel)
call?.enqueue(object : Callback<ResponseFormat.GenericResponse?> {
override fun onResponse(
call: Call<ResponseFormat.GenericResponse?>?,
response: Response<ResponseFormat.GenericResponse?>
) {
if (response.isSuccessful)
(ctx as dial.to.go.utils.Response)
.onSuccessResponse(response.body() as ResponseFormat.GenericResponse)
else
(ctx as dial.to.go.utils.Response)
.onErrorResponse(response.errorBody().toString())
}
override fun onFailure(call: Call<ResponseFormat.GenericResponse?>?, t: Throwable?) {
(ctx as dial.to.go.utils.Response)
.onFailure(t?.message)
}
})
}
}
我在响应中收到 400 错误请求。
我在没有 header 的情况下调用的 API 调用中没有发现任何问题。我的意思是,如果 SharedPreference.isAuthTokenExists(context)
returns 为假,它工作正常。而且,仅供参考,它在 POSTMAN.
中工作正常
请任何人帮助我找出解决方案。
我对 Kotlin 不太熟悉,但是您正在清除请求并且只发送 header。
HeaderInterceptor.kt
在 Java 中会是:
Request request = original.newBuilder()
.addHeader(HEADER_TOKEN, "Bearer " + SharedPreference.initialize(context).getString(Extras.AUTH_TOKEN, "")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
尝试在 ApiInterface 的 fun submitOTP 中使用 @Header("Authorization") 并将令牌作为参数传递。
我想问题是第一次,因为令牌不存在,它会在没有 HeaderInterceptor
的情况下创建 apiInterface
,然后因为它是 singleton
,它将继续使用相同的客户端和不会再添加 header,更好的选择是尽管有令牌 exists/not 只需添加 HeaderInterceptor
,因为它不会导致任何问题
@Synchronized
fun getClient(context: Context): APIInterface {
if (apiInterface == null) {
//removed the check for exists
okHttpClient.addInterceptor(HeaderInterceptor(context))
apiInterface =
Retrofit.Builder()
.baseUrl(context.resources.getString(R.string.base_url))
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient.build())
.build().create<APIInterface>(APIInterface::class.java)
}
return apiInterface as APIInterface
}
将您的HeaderInterceptor
更改为以下
class HeaderInterceptor(private val context: Context) : Interceptor {
private val HEADER_TOKEN = "token"
override fun intercept(chain: Interceptor.Chain): Response {
val modRequest = chain.request().newBuilder()
val tokenAvailable = SharedPreference.isAuthTokenExists(context)
if(tokenAvailable){
modRequest.addHeader(HEADER_TOKEN, "Bearer " + SharedPreference.initialize(context).getString(Extras.AUTH_TOKEN, "")
}
return chain.proceed(modRequest.build())
}
}
手动添加header而不调用header拦截器class函数,在RetrofitClient.kt文件
中
kHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("parameter", "value").build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(url).client(httpClient.build()).build();
我找到了解决我长时间面临的问题的方法。
我在 header 的键名中犯了一个愚蠢的错误。它应该是 Authorization
但一直保持为 token
.
非常感谢所有试图帮助我的人。
我正在开发一个 Android 应用程序,我想在其中使用 Retrofit
调用一个 API。 API 需要 header 中的授权令牌,我也添加了相同的内容。
下面是代码片段
RetrofitClient.kt
object RetrofitClient {
var apiInterface: APIInterface? = null
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(300, TimeUnit.SECONDS)
.writeTimeout(300, TimeUnit.SECONDS)
.readTimeout(180, TimeUnit.SECONDS)
@Synchronized
fun getClient(context: Context): APIInterface {
if (apiInterface == null) {
if (SharedPreference.isAuthTokenExists(context))
okHttpClient.addInterceptor(HeaderInterceptor(context))
apiInterface =
Retrofit.Builder()
.baseUrl(context.resources.getString(R.string.base_url))
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient.build())
.build().create<APIInterface>(APIInterface::class.java)
}
return apiInterface as APIInterface
}
}
HeaderInterceptor.kt
class HeaderInterceptor(private val context: Context) : Interceptor {
private val HEADER_TOKEN = "token"
override fun intercept(chain: Interceptor.Chain): Response = chain.run {
proceed(
request()
.newBuilder()
.addHeader(
HEADER_TOKEN, "Bearer " + SharedPreference.initialize(context).getString(
Extras.AUTH_TOKEN, ""
)
).build()
)
}
}
APIInterface.kt
interface APIInterface {
@POST("dialtogo/otp/verification")
fun submitOTP(@Body otpModel: OTPModel): Call<ResponseFormat.GenericResponse?>?
}
OTPRepository.kt
class OTPRepository(private var ctx: Context) {
fun submitOTP(otpModel: OTPModel) {
val apiInterface: APIInterface = RetrofitClient.getClient(ctx)
val call: Call<ResponseFormat.GenericResponse?>? = apiInterface
.submitOTP(otpModel)
call?.enqueue(object : Callback<ResponseFormat.GenericResponse?> {
override fun onResponse(
call: Call<ResponseFormat.GenericResponse?>?,
response: Response<ResponseFormat.GenericResponse?>
) {
if (response.isSuccessful)
(ctx as dial.to.go.utils.Response)
.onSuccessResponse(response.body() as ResponseFormat.GenericResponse)
else
(ctx as dial.to.go.utils.Response)
.onErrorResponse(response.errorBody().toString())
}
override fun onFailure(call: Call<ResponseFormat.GenericResponse?>?, t: Throwable?) {
(ctx as dial.to.go.utils.Response)
.onFailure(t?.message)
}
})
}
}
我在响应中收到 400 错误请求。
我在没有 header 的情况下调用的 API 调用中没有发现任何问题。我的意思是,如果 SharedPreference.isAuthTokenExists(context)
returns 为假,它工作正常。而且,仅供参考,它在 POSTMAN.
请任何人帮助我找出解决方案。
我对 Kotlin 不太熟悉,但是您正在清除请求并且只发送 header。
HeaderInterceptor.kt
在 Java 中会是:
Request request = original.newBuilder()
.addHeader(HEADER_TOKEN, "Bearer " + SharedPreference.initialize(context).getString(Extras.AUTH_TOKEN, "")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
尝试在 ApiInterface 的 fun submitOTP 中使用 @Header("Authorization") 并将令牌作为参数传递。
我想问题是第一次,因为令牌不存在,它会在没有 HeaderInterceptor
的情况下创建 apiInterface
,然后因为它是 singleton
,它将继续使用相同的客户端和不会再添加 header,更好的选择是尽管有令牌 exists/not 只需添加 HeaderInterceptor
,因为它不会导致任何问题
@Synchronized
fun getClient(context: Context): APIInterface {
if (apiInterface == null) {
//removed the check for exists
okHttpClient.addInterceptor(HeaderInterceptor(context))
apiInterface =
Retrofit.Builder()
.baseUrl(context.resources.getString(R.string.base_url))
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient.build())
.build().create<APIInterface>(APIInterface::class.java)
}
return apiInterface as APIInterface
}
将您的HeaderInterceptor
更改为以下
class HeaderInterceptor(private val context: Context) : Interceptor {
private val HEADER_TOKEN = "token"
override fun intercept(chain: Interceptor.Chain): Response {
val modRequest = chain.request().newBuilder()
val tokenAvailable = SharedPreference.isAuthTokenExists(context)
if(tokenAvailable){
modRequest.addHeader(HEADER_TOKEN, "Bearer " + SharedPreference.initialize(context).getString(Extras.AUTH_TOKEN, "")
}
return chain.proceed(modRequest.build())
}
}
手动添加header而不调用header拦截器class函数,在RetrofitClient.kt文件
中kHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("parameter", "value").build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(url).client(httpClient.build()).build();
我找到了解决我长时间面临的问题的方法。
我在 header 的键名中犯了一个愚蠢的错误。它应该是 Authorization
但一直保持为 token
.
非常感谢所有试图帮助我的人。