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
相关产品推荐
相关产品推荐

