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

Android Kotlin Retrofit发起多参数POST请求返回500错误排查

问题成因

请求失败的核心原因是序列化配置和传参类型不匹配,具体触发点如下:

  • 你为Retrofit配置的序列化转换器是GsonConverterFactory,但接口的@Body参数使用了org.json.JSONObject类型。Gson无法正确识别该类的结构,不会按照你传入的JSON字符串内容生成请求体,最终发送给后端的是结构畸形的JSON内容,后端解析请求体失败直接返回500错误。
  • 接口声明的返回值是Call<String>,但仅配置了Gson转换器,Gson会默认尝试将响应内容按JSON结构解析,如果接口返回的是普通纯文本字符串,会触发解析异常,最终读取到的响应体为null。
  • Postman可以正常请求是因为Postman直接发送你手动输入的原始请求体内容,不存在代码层面的序列化转换逻辑,和Android端的请求执行逻辑有本质区别。
修复方案

按以下步骤调整代码即可恢复正常请求:

  • 第一步:替换请求体传参类型,不要使用org.json.JSONObject,改用Gson可以正常序列化的Map结构或者自定义数据类,以Map为例,构建和你需求完全匹配的请求体:
// 构建对应结构的请求体
val requestBody = mapOf(
    "some_field" to mapOf(
        "55" to "29"
    )
)

同时修改Retrofit接口定义的@Body参数类型:

@POST("customers/{customers}/venues/{venues}/abcfiles/sasfordownload")
fun makeRequestForfileUrl(
    @HeaderMap token: Map<String, String>,
    @Path("customers") customers: Int,
    @Path("venues") venues: Int,
    @Query("licenseid") licenceId: String,
    @Query("ispreproduction") ispreproduction: Boolean,
    @Body body: Map<String, Any> // 替换原有的JSONObject类型
): Call<String>
  • 第二步:添加字符串响应转换器,支持直接解析String类型的返回值。注意ScalarsConverterFactory必须放在GsonConverterFactory之前声明,否则不会生效。
    先引入和你当前Retrofit版本匹配的scalars依赖,之后修改Retrofit实例构建代码:
fun requestApi(mContext: Context): ApiInterface {
    return Retrofit.Builder()
        .baseUrl(apiUrl)
        // 优先添加Scalars转换器处理纯文本/字符串响应
        .addConverterFactory(ScalarsConverterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .client(
            OkHttpClient.Builder()
                .addInterceptor(NetworkConnectionInterceptor(mContext))
                // 建议将日志拦截器级别设置为BODY,可直接查看实际发出的请求/响应内容
                .addInterceptor(httpLoggingInterceptor)
                .build()
        )
        .build()
        .create(ApiInterface::class.java)
}
  • 第三步:发起请求时,传入之前构建的requestBody替换原有的JSONObject实例即可:
val headerMap = HashMap<String, String>().apply {
    put("Authorization", "Bearer $fetchedToken")
    put("Content-Type", "application/json")
}

val requestCall = ServiceGenerator.requestApi(mContext).makeRequestForfileUrl(
    headerMap,
    customerId,
    venueId,
    licenceId,
    true,
    requestBody
)

排查提示:将HttpLoggingInterceptor的日志级别设置为BODY后,可以直接在Logcat中看到Android端实际发出的请求头、请求地址、请求体、响应内容,和Postman的请求参数做逐行对比,可快速定位所有参数差异问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:18:15