如何通过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
相关产品推荐
相关产品推荐

