Retrofit是Square公司开发的一个类型安全的HTTP客户端库,用于Android和Java应用程序。它将HTTP API转换为Java/Kotlin接口,简化了网络请求的处理。
当API调用返回空白正文时,可能有以下几种原因:
原因:服务器确实返回了空内容(HTTP 204 No Content或类似状态码) 解决方案:
// 修改返回类型为Response<Void>或Unit
@GET("endpoint")
suspend fun getData(): Response<Void>
原因:响应格式与预期模型不匹配 解决方案:
ResponseBody
作为返回类型查看原始响应@GET("endpoint")
suspend fun getData(): Response<ResponseBody>
// 然后可以这样获取原始字符串
val responseBody = response.body()?.string()
原因:拦截器修改或丢弃了响应体 解决方案:
val client = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.build()
原因:服务器未正确设置Content-Length头 解决方案:
val client = OkHttpClient.Builder()
.addNetworkInterceptor { chain ->
val originalResponse = chain.proceed(chain.request())
originalResponse.newBuilder()
.removeHeader("Transfer-Encoding")
.removeHeader("Content-Length")
.build()
}
.build()
原因:响应使用了非UTF-8编码 解决方案:
val moshi = Moshi.Builder()
.add(String::class.java, object : JsonAdapter<String>() {
override fun fromJson(reader: JsonReader): String? {
return reader.nextString() // 处理编码问题
}
// ...
})
.build()
原因:Retrofit将空响应视为错误 解决方案:
@Nullable
注解@GET("endpoint")
suspend fun getData(): @Nullable MyDataModel
// 1. 添加日志拦截器
val loggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build()
// 2. 创建Retrofit实例
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttpClient)
.addConverterFactory(MoshiConverterFactory.create())
.build()
// 3. 定义API接口
interface ApiService {
@GET("data")
suspend fun getData(): Response<ResponseBody> // 使用ResponseBody获取原始响应
}
// 4. 调用API并处理响应
try {
val response = retrofit.create(ApiService::class.java).getData()
if (response.isSuccessful) {
val rawResponse = response.body()?.string()
Log.d("API_RESPONSE", "Raw response: $rawResponse")
} else {
Log.e("API_ERROR", "Error: ${response.code()} ${response.message()}")
}
} catch (e: Exception) {
Log.e("API_EXCEPTION", "Exception: ${e.message}")
}
通过以上方法,你可以逐步排查API调用返回空白正文的具体原因,并根据实际情况采取相应的解决方案。