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

Android中使用Retrofit上传多表单数据及图片返回status0问题求解

Retrofit上传文件接口返回成功但状态值为0的解决方法

问题背景

使用Retrofit上传文件和表单信息时,接口返回成功但状态值为0,Postman中用文件类型的photo参数能正常请求,推测是代码中文件传递方式有误。

问题原因分析

  1. 冗余的Content-Type头:接口中手动设置了Content-Type: multipart/form-data,但Retrofit在处理@Multipart注解时会自动生成正确的请求头,手动添加反而可能导致请求格式异常。
  2. 文件MediaType不精确:使用image/*作为文件的MediaType,部分服务端无法准确识别,可能导致文件解析失败。
  3. 参数写法不统一:部分参数用toRequestBody,部分用RequestBody.create,虽然功能一致,但统一写法更易维护。

修正后的代码

1. MyAPI接口(移除冗余Header)

@Multipart
@POST("edit_userinfo")
@Headers(
    "Accept: */*"
)
fun editProfile(
    @Part("languges") lang: RequestBody,
    @Part("user_id") userId: RequestBody,
    @Part("name") name: RequestBody,
    @Part("gender") gender: RequestBody,
    @Part("keyword") keyword: RequestBody,
    @Part("mobile") mobile: RequestBody,
    @Part image: MultipartBody.Part
): Call<UploadResponse>

// Retrofit实例保持不变
return Retrofit.Builder()
            .baseUrl("http://phpstack-916737-3182297.cloudwaysapps.com/")
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(MyAPI::class.java)

2. MainActivity请求代码(优化MediaType和参数)

// 统一定义文本类型的MediaType
val textType = "text/plain".toMediaTypeOrNull()

// 统一使用toRequestBody创建文本参数
val lang = "English".toRequestBody(textType)
val userId = "1".toRequestBody(textType)
val name = "Test12".toRequestBody(textType)
val gender = "male".toRequestBody(textType)
val mobno = "1212121212".toRequestBody(textType)
val keyword = "**********".toRequestBody(textType)

// 根据文件实际类型设置精确的MediaType,比如image/jpeg、image/png
val imageType = when (file.extension.lowercase()) {
    "png" -> "image/png".toMediaTypeOrNull()
    "jpg", "jpeg" -> "image/jpeg".toMediaTypeOrNull()
    else -> "image/*".toMediaTypeOrNull()
} ?: "image/*".toMediaTypeOrNull()

// 使用asRequestBody简化文件RequestBody创建
val imagePart = MultipartBody.Part.createFormData(
    "photo",
    file.name,
    file.asRequestBody(imageType)
)

// 发起请求
val apiCall = MyAPI().editProfile(lang, userId, name, gender, keyword, mobno, imagePart)
apiCall.enqueue(object : Callback<UploadResponse> {
    override fun onFailure(call: Call<UploadResponse>, t: Throwable) {
        Log.e("TAG", "onFailure: $t")
        t.printStackTrace()
        layout_root.snackbar(t.message!!)
    }

    override fun onResponse(call: Call<UploadResponse>, response: Response<UploadResponse>) {
        response.body()?.let {
            Log.e("TAG", "onResponse: success $it")
            layout_root.snackbar("Status -> $it")
        }
    }
})

额外调试建议

  • 添加OkHttp日志拦截器,打印完整的请求内容,对比Postman的请求格式,确认参数名、文件类型是否完全匹配。
  • 检查服务端是否对文件大小、格式有校验限制,或者photo参数名是否存在大小写错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 12:35:20