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

Android/Kotlin/Retrofit中带Body的GET请求返回布尔值问题排查

解决方案

问题1:GET请求携带请求体不被Retrofit支持

HTTP规范中GET请求通常不携带请求体,尽管部分服务器允许,但Retrofit默认不会为GET请求发送请求体。需要给OkHttpClient添加拦截器,通过请求伪装实现GET带Body的需求:

val okHttpClient = OkHttpClient.Builder()
    .addInterceptor { chain ->
        val originalRequest = chain.request()
        if (originalRequest.method == "GET" && originalRequest.body != null) {
            // 用POST发送请求,通过请求头告知服务器实际是GET请求
            val modifiedRequest = originalRequest.newBuilder()
                .method("POST", originalRequest.body)
                .header("X-HTTP-Method-Override", "GET")
                .build()
            chain.proceed(modifiedRequest)
        } else {
            chain.proceed(originalRequest)
        }
    }
    .build()

将配置好的OkHttpClient传入Retrofit实例:

val retrofit = Retrofit.Builder()
    .baseUrl(BASE_URL)
    .client(okHttpClient)
    .addConverterFactory(GsonConverterFactory.create())
    .build()

问题2:裸布尔值响应解析失败

接口返回的true/false属于裸JSON值,Gson默认无法直接解析为Boolean类型,有两种解决方式:

方案A:手动解析ResponseBody

修改API接口定义,直接返回ResponseBody:

@GET("api/is_correct")
suspend fun isCorrect(@Body email: Email): ResponseBody

在ViewModel中手动读取并解析:

fun checkIfCorrect(input: String) {
    val email = Email(input)
    viewModelScope.launch {
        try {
            val responseBody = RetrofitInstance.api.isCorrect(email)
            val result = responseBody.string().toBooleanStrict()
            Log.e(TAG, "校验结果:$result")
        } catch (e: Exception){
            Log.e(TAG, "错误详情:${e.message}")
        }
    }
}

方案B:自定义Gson转换器支持裸值解析

创建布尔值的自定义TypeAdapter:

class BooleanTypeAdapter : TypeAdapter<Boolean>() {
    override fun write(out: JsonWriter, value: Boolean?) {
        out.value(value)
    }

    override fun read(`in`: JsonReader): Boolean {
        return when (`in`.peek()) {
            JsonToken.BOOLEAN -> `in`.nextBoolean()
            JsonToken.STRING -> `in`.nextString().toBooleanStrict()
            JsonToken.NUMBER -> `in`.nextDouble() != 0.0
            else -> throw JsonSyntaxException("预期布尔值,实际为${`in`.peek()}")
        }
    }
}

注册适配器到Gson实例:

val gson = GsonBuilder()
    .registerTypeAdapter(Boolean::class.java, BooleanTypeAdapter())
    .registerTypeAdapter(Boolean::class.javaObjectType, BooleanTypeAdapter())
    .create()

将自定义Gson传入Retrofit:

val retrofit = Retrofit.Builder()
    .baseUrl(BASE_URL)
    .client(okHttpClient)
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build()

此时API接口可继续使用Response<Boolean>作为返回类型:

@GET("api/is_correct")
suspend fun isCorrect(@Body email: Email): Response<Boolean>

额外建议

  • 优先选择方案A,配置简单且避免自定义转换器的潜在问题。
  • 若条件允许,建议和后端沟通调整接口:要么改为POST请求携带Body,要么将布尔值包装为标准JSON对象(如{"result": true}),更符合HTTP规范和常规接口设计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:39:27