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

Android(Kotlin)中Retrofit Post请求数据未送达服务器求助

排查Retrofit POST请求无数据到达服务端的问题

以下是针对你遇到的问题的具体排查方向和修复建议:


1. 先检查请求的真实响应状态

你当前的代码仅打印"good job"就判定请求成功,但**onResponse回调只代表请求到达服务端并收到响应,不代表业务逻辑成功**。先修改回调打印完整响应信息,定位问题:

service.createUsers(usersInfo).enqueue(object: Callback<ResponseBody> {
    override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
        Log.d("Retrofit", "响应码: ${response.code()}")
        Log.d("Retrofit", "请求是否成功: ${response.isSuccessful}")
        // 打印服务端返回的错误详情(若存在)
        if (!response.isSuccessful) {
            val errorContent = response.errorBody()?.string()
            Log.d("Retrofit", "错误内容: $errorContent")
        }
        // 打印实际发送的请求体,确认数据是否正确
        val requestContent = call.request().body()?.toString()
        Log.d("Retrofit", "发送的请求体: $requestContent")
    }

    override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
        Log.d("Retrofit", "请求失败原因: ${t.message}")
        t.printStackTrace()
    }
})

通过这些日志你能明确:

  • 服务端返回的是2xx成功码,还是4xx/5xx错误码
  • 客户端实际发送的请求体是否包含id、name、uid字段

2. 修正Moshi序列化逻辑

你的数据类字段为可空类型,若服务端要求字段必须存在(即使值为null),或字段名与服务端定义不匹配,会导致序列化后的数据不符合要求:

  • 若服务端字段名与你的数据类完全一致,当前Moshi配置(已添加KotlinJsonAdapterFactory)可正常处理可空字段,无需修改数据类;
  • 若服务端字段名与你的数据类不一致(比如服务端用user_id而你用id),需添加@Json注解映射:
import com.squareup.moshi.Json

data class UsersEntity(
    @Json(name = "user_id") val id: Int? = null,
    @Json(name = "user_name") val name: String? = null,
    @Json(name = "user_uid") val uid: String? = null
)

3. 移除多余的线程包裹

Retrofit的enqueue方法本身就是异步执行的,手动开启thread完全多余,还可能引发线程问题,直接删除即可。


4. 匹配服务端的参数接收格式

如果服务端要求接收form-data或x-www-form-urlencoded格式而非JSON,用@Body注解会导致数据无法被解析,需修改接口定义:
改用@FormUrlEncoded和@Field注解传递参数:

interface UserService {
    @FormUrlEncoded
    @POST("createusers")
    fun createUsers(
        @Field("id") id: Int?,
        @Field("name") name: String?,
        @Field("uid") uid: String?
    ): Call<ResponseBody>
}

调用时直接传入参数:

service.createUsers(3, "Alex", "164E92FC-D37A").enqueue(...)

5. 优化Retrofit实例创建逻辑

每次点击按钮都重复创建Retrofit和Service实例是不必要的,建议封装成单例避免重复初始化:

object RetrofitInstance {
    private val moshi = Moshi.Builder()
        .add(KotlinJsonAdapterFactory())
        .build()

    private val retrofit = Retrofit.Builder()
        .baseUrl("https://api.*****.com/")
        .addConverterFactory(MoshiConverterFactory.create(moshi))
        .build()

    val userService: UserService by lazy {
        retrofit.create(UserService::class.java)
    }
}

按钮点击时直接调用:

val usersInfo = UsersEntity(3, "Alex", "164E92FC-D37A")
RetrofitInstance.userService.createUsers(usersInfo).enqueue(...)

6. 用抓包工具确认请求细节

如果以上步骤仍未定位问题,建议用Charles或Fiddler抓包,查看POST请求的:

  • 请求头的Content-Type是否为application/json(使用@Body时应为此值)
  • 请求体的JSON内容是否正确包含三个字段

抓包能100%确认客户端发送的数据是否符合服务端要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:25:21