繁体   English   中英

如何在 Kotlin 中使用 Retrofit 获取响应头?

[英]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。

例子:

retrofit请求

    @POST(YOUR_ROAD) // Retrofit road
        suspend fun connect(
            @Body credentials: CredentialsObjectBody
        ): Response<ConnectionObjectResponse>

存储库调用 retrofit 请求

    // 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))
        }
    }

数据状态:

DataState 是一个密封的 class 允许区分发射状态
    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
            */
        }
    }

如何调用 Kotlin 流程以在 IO 线程上启动它以防止阻塞主(或 UI)线程

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM