You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ViewModel中通过Retrofit2与RxJava获取响应头?

如何在ViewModel中获取Retrofit+RxJava请求的响应头

要拿到服务响应的特定头,核心是让Retrofit返回包含完整响应信息的retrofit2.Response对象,而不是直接返回响应体。下面是具体的修改步骤:

1. 修改ApiService接口的返回类型

把原来直接返回Single<ServiceResponse>改成返回Single<retrofit2.Response<ServiceResponse>>,这样Retrofit会把响应头、状态码、响应体等所有信息封装进来:

interface ApiService {
    @GET("/repos/{owner}/data")
    fun loadData(
        @Path("owner") owner: String,
        @Query("page") page: Int,
        @Query("per_page") perPage: Int
    ): Single<retrofit2.Response<ServiceResponse>> // 调整返回类型
}

2. 更新NetworkProvider的方法返回类型

对应修改NetworkProvider中loadDataSingle的返回类型,和ApiService保持一致:

class NetworkProvider {
    private lateinit var authService: ApiService

    init {
        createService()
    }

    private fun createService() {
        // 原有的Retrofit初始化逻辑不需要改动
    }

    // 调整返回类型
    fun loadDataSingle(owner: String, page: Int, perPage: Int): Single<retrofit2.Response<ServiceResponse>> {
        return authService.loadData(owner, page, perPage)
    }
}

3. 更新Repository的方法返回类型

同样修改Repository中loadDataSingle的返回类型:

class Repository {
    private val networkProvider = NetworkProvider()

    // 调整返回类型
    fun loadDataSingle(owner: String, page: Int, perPage: Int): Single<retrofit2.Response<ServiceResponse>> {
        return networkProvider.loadDataSingle(owner, page, perPage)
    }
}

4. 在ViewModel中读取响应头

现在在subscribe回调里,你会收到retrofit2.Response<ServiceResponse>对象,通过response.headers()可以获取所有响应头,用get("目标头名称")拿到特定头;响应体依然从response.body()获取:

class MyViewModel(val repository: Repository) : ViewModel {
    private val disposable = CompositeDisposable()
    val responseLiveData = MutableLiveData<SingleEvent<ServiceResponse>>()
    val errorLiveData = MutableLiveData<SingleEvent<Boolean>>()

    private fun loadDataPaged(owner: String, page: Int, perPage: Int) {
        disposable.add(
            repository.loadDataSingle(owner, page, perPage)
                .subscribeOn(Schedulers.io())
                .subscribe({ response ->
                    // 示例:获取名为"X-Total-Count"的响应头
                    val totalCount = response.headers().get("X-Total-Count")
                    // 这里可以根据需求处理拿到的头信息,比如存入变量或其他LiveData

                    // 获取原响应体并发送到LiveData
                    response.body()?.let { serviceResponse ->
                        responseLiveData.postValue(SingleEvent(serviceResponse))
                    } ?: run {
                        // 处理响应体为空的异常情况
                        errorLiveData.postValue(SingleEvent(true))
                    }
                }, { exc ->
                    errorLiveData.postValue(SingleEvent(true))
                })
        )
    }
}

内容的提问来源于stack exchange,提问作者vitiello.antonio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:44:16