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

Retrofit图片上传返回400错误请求 寻求技术排查帮助

解决Retrofit图片上传返回400错误的问题

看起来你在Retrofit实现图片上传时碰到了400 Bad Request的坑,我帮你梳理下可能的问题和修复方案:

核心问题分析及修复步骤

  • 手动设置Content-Type头引发冲突
    当使用@Multipart注解时,Retrofit会自动生成符合要求的multipart/form-data请求头,还会自动添加boundary分隔符。你手动通过@Header("Content-Type")设置json类型的头,直接和Multipart请求的格式要求冲突,这大概率是导致400错误的元凶。

    修复:直接移除@Header("Content-Type") String json这个参数,让Retrofit自动处理Content-Type即可。

  • 普通参数需用RequestBody而非直接传String
    你的type和user_id直接用String类型配合@Part注解,不符合Multipart请求的参数规范,服务器根本没法正确解析这些字段。

    修复:把这类参数改成RequestBody类型,接口定义调整为:

    @Part("type") RequestBody type,
    @Part("user_id") RequestBody userId
    

    调用时通过RequestBody.create(MediaType.parse("text/plain"), "你的参数值")来创建对应的RequestBody对象。

  • 核对参数名与服务器要求完全匹配
    务必确认type、user_id、image_path这些参数名和后端接口文档的要求完全一致——大小写、下划线、拼写都不能错,很多400错误都是因为参数名不匹配导致的。

修复后的完整接口示例

public interface SupportInterface { 
    // 聊天图片上传接口
    @Multipart 
    @POST("/api/upload-image") 
    Call<ResponseBody> uploadChatPhoto(
        @Header("Authorization") String token, 
        @Header("Cache-Control") String cache, 
        @Part("type") RequestBody type, 
        @Part("user_id") RequestBody userId, 
        @Part MultipartBody.Part image_path
    ); 
}

接口调用示例代码

// 创建普通参数的RequestBody
RequestBody typeBody = RequestBody.create(MediaType.parse("text/plain"), "chat");
RequestBody userIdBody = RequestBody.create(MediaType.parse("text/plain"), "你的用户ID");

// 创建图片的MultipartBody.Part
File imageFile = new File("本地图片路径");
RequestBody imageRequestBody = RequestBody.create(MediaType.parse("image/*"), imageFile);
MultipartBody.Part imagePart = MultipartBody.Part.createFormData("image_path", imageFile.getName(), imageRequestBody);

// 发起请求
SupportInterface api = RetrofitClient.getInstance().create(SupportInterface.class);
Call<ResponseBody> call = api.uploadChatPhoto("Bearer " + token, "no-cache", typeBody, userIdBody, imagePart);
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        // 处理成功响应逻辑
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 处理请求失败逻辑
    }
});

额外建议:可以用Charles、Fiddler这类抓包工具查看实际发送的请求内容,对比后端要求的格式,能更快定位细节问题——比如检查请求头是否正确、参数是否都包含在请求体里。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:07:48