![](/img/trans.png)
[英]How do I get response headers with RxAndroid + Retrofit in Kotlin?
[英]how to get response headers using Retrofit in Kotlin?
您好,我正在使用 retrofit 和 rxjava2 进行异步处理
在与服务器开发人员交谈时,我必须从 header 中获取值。
但是,我不知道如何从我使用的方法中获取 header。 我知道如何从 Call Response 获取,但我不知道如何带 header,因为使用的方法不同。
我的改造 2 class
private val retrofit: Retrofit = Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(client())
.baseUrl(serverIp)
.build()
val userApi: UserAPI = retrofit.create(UserAPI::class.java)
我的 model class
@POST("user")
fun login(
@Body loginRequest : LoginRequest
) : Single<UserResponse>
data class LoginRequest(
val phone: String?,
@SerializedName("gender")
val gender: String?,
@SerializedName("age")
val age: String?,
@SerializedName("email")
val email: String?
)
data class UserResponse (
override var status: Int,
override var message: String,
override var timestamp: String,
var data: Data
) : CommonResponse() {
data class Data(
var username: String?,
var token: String?
)
}
我的视图模型(接收)
addDisposable(
model.loginBody(loginRequest)
.subscribeOn(Schedulers.io())
.subscribe({
_loginResult.postValue(it)
}, {
Timber.d("response error, message : ${it.localizedMessage}")
})
)
我目前的情况如下。 需要登录后服务器返回的headers,从okhttp日志中可以看到,但是具体header不知道怎么获取
要检索响应标头和其他有用信息,您可以使用 retrofit2 package 中的Response
类型。要使用此方法,请将登录方法的返回类型更改为Single<retrofit2.Response<UserResponse>>
@POST("user")
fun login( @Body loginRequest : LoginRequest): Single<retrofit2.Response<UserResponse>>
现在在您的 ViewModel 中检索标头
addDisposable(
model.loginBody(loginRequest)
.subscribeOn(Schedulers.io())
.subscribe({
val headers = it.headers() // do something with headers
val data = it.body()
_loginResult.postValue(data)
}, {
Timber.d("response error, message : ${it.localizedMessage}")
})
)
不是解决问题的问题,但即使已经晚了,因为您使用的是 Kotlin,更好的解决方案是从 rxJava 迁移到 Kotlin Flow。 它允许您使用suspend
函数执行 retrofit 调用,然后使用 Kotlin Flow 在 IO 线程上执行 rxJava 的工作。
它还允许您以更简单的方式使用Response<T>
retrofit object。
@POST(YOUR_ROAD) // Retrofit road
suspend fun connect(
@Body credentials: CredentialsObjectBody
): Response<ConnectionObjectResponse>
// The function is suspending the thread with suspend keyword
suspend fun yourFunction(): Flow<DataState<TypeForEmitter>> = flow {
try {
body.clientId = sessionPrefs.deviceName!!
val connectionResponse =
majorApi.connect(
// what you need to put in the body
)
.apply {
if (isSuccessful) {
body()?.let {
// Here you can use what's in the request body
emit(DataState.Success(it))
} ?: throw Exception("Request body was null")
} else {
throw Exception(headers()["message"]) // use throw to handle the error in the catch
}
}
} catch (e: Exception) {
Log.e(TAG, "error: ${e.message}")
emit(DataState.Error(e))
}
}
withContext(Dispatchers.IO) {
yourFunction().onEach {
/*
onEach is like onNext, but emits every type of error, compared to rxJava
that differentiates next/success, complete and error events
*/
}
}
withContext(Dispatchers.IO) { yourFunction().onEach { /* onEach is like onNext, but emits every type of error, compared to rxJava that differentiates next/success, complete and error events */ } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.