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

如何通过Retrofit发送MultipartBody数组?

如何用Retrofit正确发送MultipartBody数组?

我看你之前能成功发送单个包含图片和属性的MultipartBody,但尝试发送MultipartBody数组时遇到了请求格式异常的问题——这其实是因为Retrofit并不支持直接将MultipartBody[]作为@Body参数来序列化,它会把数组当成普通对象处理,导致请求体结构完全错乱,出现你看到的乱码和错误格式。

问题根源

你原来的接口定义@Body MultipartBody[] requestsBody是行不通的,因为Multipart本身就是多部分表单格式,数组形式的MultipartBody无法被Retrofit正确解析成符合HTTP规范的请求体。

正确解决方案:合并所有内容到单个MultipartBody

正确的做法是把所有课程的属性和图片都合并到同一个MultipartBody.Builder中,通过给字段名添加数组下标(比如skill[0]、skill[1])来区分不同的课程条目,这样后端就能正确识别多个课程的数据。

1. 修改接口定义

保持接口和单个请求时一致,接收单个RequestBody即可:

@POST("test_request")
Call<ResponseBody> addCourses(@Body RequestBody requestBody);

2. 修改请求体生成方法

把多个课程的所有表单字段和文件都添加到同一个MultipartBody里:

private MultipartBody getMultiCoursesBody() {
    MultipartBody.Builder builder = new MultipartBody.Builder();
    builder.setType(MultipartBody.FORM);

    // 遍历所有课程
    for (int courseIdx = 0; courseIdx < coursesAddedArrayList.size(); courseIdx++) {
        CoursesAdded course = coursesAddedArrayList.get(courseIdx);
        
        // 添加课程的属性,用下标区分不同课程
        builder.addFormDataPart("skill[" + courseIdx + "]", course.getCourse_name());
        builder.addFormDataPart("certificate_from[" + courseIdx + "]", course.getCourse_location());
        builder.addFormDataPart("certificate_date[" + courseIdx + "]", "null");
        
        // 添加当前课程的三张图片
        List<String> filePaths = Arrays.asList(
            course.getImag1(),
            course.getImag2(),
            course.getImag3()
        );
        
        for (String filePath : filePaths) {
            File file = new File(filePath);
            // 字段名根据后端需求调整:如果后端接受批量file[],可直接用"file[]"
            // 若要和课程一一对应,用"file[" + courseIdx + "][]"更清晰
            builder.addFormDataPart("file[" + courseIdx + "][]", file.getName(),
                RequestBody.create(MediaType.parse("image/*"), file));
        }
    }

    return builder.build();
}

3. 调用接口

现在直接把生成的单个MultipartBody传入接口即可:

MultipartBody requestBody = getMultiCoursesBody();
apiService.addCourses(requestBody).enqueue(new Callback<ResponseBody>() {
    // 你的回调逻辑
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        // 处理成功响应
    }

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

额外注意点

  • 关于文件的MediaType:尽量使用具体的图片类型(比如image/jpeg、image/png),如果不确定可以用image/*代替,不要用multipart/form-data——这是整个请求的类型,不是单个文件的类型。
  • 字段名格式:要和后端约定好,比如后端是否期望skill[](不指定下标)还是skill[0]这种带下标格式,确保前后端逻辑一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:24:38