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

Retrofit中@Part与@FieldMap混合使用报错问题咨询

解决Retrofit中@Part与@FormUrlEncoded冲突的问题

嘿,这个错误的根源其实很直白——你把两种互斥的请求编码注解混在一起用了!

问题到底出在哪?

你给接口方法加了@FormUrlEncoded,这个注解是用来告诉Retrofit以application/x-www-form-urlencoded格式发送普通表单数据的;但同时你又用了@Part来传递文件列表,而@Part是专门为multipart/form-data格式设计的(只有这种格式才支持上传文件)。这俩注解根本不能共存于同一个接口方法,所以Retrofit直接抛出了参数不合法的异常。

修复方案

把@FormUrlEncoded替换成@Multipart,同时把@FieldMap改成@PartMap(因为multipart格式下不能用@Field或@FieldMap),修改后的接口代码如下:

@Multipart
@POST("index.php")
Call<MyObjResponse> myCall(
    @Part List<MultipartBody.Part> files,
    @PartMap Map<String, RequestBody> params
);

调用时的小细节

  1. 传递键值对参数时,需要把String类型的参数转换成RequestBody,比如:
Map<String, RequestBody> params = new HashMap<>();
// 普通文本参数用text/plain类型
params.put("username", RequestBody.create(MediaType.parse("text/plain"), "john_doe"));
params.put("age", RequestBody.create(MediaType.parse("text/plain"), "28"));

如果你的Retrofit版本在2.4.0及以上,还能用上更简洁的写法:

params.put("username", RequestBody.create("john_doe", MediaType.parse("text/plain")));
  1. 文件部分的构建不用改,还是按照你之前的方式创建MultipartBody.Part就行,比如:
File imageFile = new File("/sdcard/photo.jpg");
RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"), imageFile);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("avatar", imageFile.getName(), fileBody);

这样修改后,Retrofit就会以正确的multipart/form-data格式发送请求,既能带上你的文件列表,也能传递键值对参数,不会再抛出异常啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:22:10