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

Retrofit GET请求无法获取货币转换API返回结果问题排查

Retrofit调用RapidAPI货币转换API时response.body为空的解决办法

问题背景

用Retrofit调用RapidAPI上的Currency Converter 18 API发起GET请求,确认URL正确,但response.body()始终返回空值。相关代码如下:

Retrofit接口定义

interface CurrencyConverterEndpoint {

    @GET("api/v1/convert")
    fun getCurrencyConverter(@Query("from") from: String, @Query("to") to: String, @Query("amount") amount: String): Call<ConvertModel>

}

数据模型类

data class ConvertModel (
    @SerializedName("from")
    val from: String,
    @SerializedName("to")
    val to: String,
    @SerializedName("amountToConvert")
    val amountToConvert: Int,
    @SerializedName("convertedAmount")
    val convertedAmount: Double
)

请求调用代码

fun getCurrencyConverter(
    from: String,
    to: String,
    amount: String,
    listener: RetrofitListener<ConvertModel>
) {
    val getCurrencyConverterCallback = endpoint.getCurrencyConverter(from, to, amount)
    getCurrencyConverterCallback.enqueue(object : Callback<ConvertModel> {
        override fun onResponse(call: Call<ConvertModel>, response: Response<ConvertModel>) {
            if (response.code() == RetrofitConstants.SUCCESS) {
                val s = response
            }
        }

        override fun onFailure(call: Call<ConvertModel>, t: Throwable) {
            listener.onError(t.message ?: "Erro.")
        }

    })
}

API返回的JSON结构示例:

{
  "status": "success",
  "data": {
    "from": "USD",
    "to": "EUR",
    "amountToConvert": 100,
    "convertedAmount": 92.34
  }
}

问题根源

  1. 缺少RapidAPI必填请求头:RapidAPI所有接口都要求携带X-RapidAPI-Key和X-RapidAPI-Host,未添加的话请求会被拒绝,返回内容不符合预期,导致Retrofit解析失败。
  2. 模型类不匹配返回结构:API返回的是嵌套JSON,外层包含status和data字段,你直接用ConvertModel对应内层数据,没有外层包装类,Retrofit无法将JSON解析为目标对象。
  3. 参数类型错误:amount参数API要求为数值类型,你传入的是String类型,可能导致参数解析异常。

解决步骤

1. 添加RapidAPI请求头

可以在接口方法上直接添加,或在Retrofit客户端全局配置:

interface CurrencyConverterEndpoint {

    @GET("api/v1/convert")
    @Headers(
        "X-RapidAPI-Key: 你的RapidAPI密钥",
        "X-RapidAPI-Host: currency-converter18.p.rapidapi.com"
    )
    fun getCurrencyConverter(
        @Query("from") from: String,
        @Query("to") to: String,
        @Query("amount") amount: Int // 改为Int类型,匹配API要求
    ): Call<CurrencyResponse>

}

2. 修正模型类,匹配嵌套结构

新增外层响应类,包裹原有的ConvertModel:

// 外层响应包装类
data class CurrencyResponse(
    @SerializedName("status")
    val status: String,
    @SerializedName("data")
    val data: ConvertModel
)

// 原数据类保持不变
data class ConvertModel (
    @SerializedName("from")
    val from: String,
    @SerializedName("to")
    val to: String,
    @SerializedName("amountToConvert")
    val amountToConvert: Int,
    @SerializedName("convertedAmount")
    val convertedAmount: Double
)

3. 调整请求代码适配新响应类型

fun getCurrencyConverter(
    from: String,
    to: String,
    amount: Int, // 同步改为Int类型
    listener: RetrofitListener<CurrencyResponse>
) {
    val callback = endpoint.getCurrencyConverter(from, to, amount)
    callback.enqueue(object : Callback<CurrencyResponse> {
        override fun onResponse(call: Call<CurrencyResponse>, response: Response<CurrencyResponse>) {
            if (response.isSuccessful) {
                response.body()?.let {
                    // 从响应中取出转换结果
                    val result = it.data
                    listener.onSuccess(it)
                } ?: listener.onError("响应体为空")
            } else {
                // 打印错误信息方便排查
                val errorMsg = response.errorBody()?.string()
                listener.onError("请求失败:${response.code()},详情:$errorMsg")
            }
        }

        override fun onFailure(call: Call<CurrencyResponse>, t: Throwable) {
            listener.onError(t.message ?: "请求失败")
        }

    })
}

4. 调试技巧

开启Retrofit日志拦截器,查看实际请求和响应内容,快速定位问题:

val loggingInterceptor = HttpLoggingInterceptor().apply {
    level = HttpLoggingInterceptor.Level.BODY
}

val okHttpClient = OkHttpClient.Builder()
    .addInterceptor(loggingInterceptor)
    .build()

val retrofit = Retrofit.Builder()
    .baseUrl("https://currency-converter18.p.rapidapi.com/")
    .client(okHttpClient)
    .addConverterFactory(GsonConverterFactory.create())
    .build()

日志会显示请求头、参数、返回的JSON内容,帮助确认问题所在。


内容的提问来源于stack exchange,提问作者Antony Lajes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:35:36