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 );
调用时的小细节
- 传递键值对参数时,需要把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")));
- 文件部分的构建不用改,还是按照你之前的方式创建
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
相关产品推荐
相关产品推荐

