Java Retrofit发送Multipart带图POST请求时JsonObject转字符串问题
问题根因
- 你创建
aadharDetails请求段时直接调用HashMap.toString(),该方法输出的是{key=value}格式的字符串,不符合JSON语法规范(标准JSON要求键、字符串值必须用双引号包裹) - 没有给该请求段指定
application/json的Content-Type,Retrofit默认会把它识别为text/plain类型的普通字符串,服务端收到后自然按字符串解析,不会识别为JSON对象。
修复步骤
1. 调整Api接口定义
将接口中data参数的类型从MultipartBody.Part修改为指定字段名的RequestBody,同时建议布尔类型参数也改为RequestBody传递,避免序列化格式异常:
@Multipart @POST("operator/upload") Call<JsonObject> upload(@Header ("Authorization") String t, @Part MultipartBody.Part img, @Part("fullName") RequestBody name, @Part("fatherName") RequestBody fathername, @Part("aadharNumber") RequestBody aadharnumber, @Part("dob") RequestBody dob, @Part("registeredAddress") RequestBody address, @Part("gender") RequestBody gender, @Part("plantId") RequestBody plant, @Part("aadharDetails") RequestBody data, @Part("authorized") RequestBody auth, @Part("verified") RequestBody ver);
2. 替换delta请求体的创建逻辑
先将HashMap转换为标准JSON字符串,再创建带JSON类型声明的RequestBody,替换原有创建delta的代码:
// 导入需要的类:okhttp3.MediaType、okhttp3.RequestBody、org.json.JSONObject HashMap<String, String> num2 = new HashMap<>(); // ...... 原有put字段的逻辑保留不变 ...... // 把HashMap转成标准JSON对象,自动生成符合语法的JSON字符串 JSONObject aadharJson = new JSONObject(num2); // 指定该请求段的类型为JSON MediaType jsonMediaType = MediaType.parse("application/json; charset=utf-8"); RequestBody delta = RequestBody.create(jsonMediaType, aadharJson.toString()); // 布尔值也按指定类型创建RequestBody,避免格式问题 RequestBody authBody = RequestBody.create(MediaType.parse("text/plain"), String.valueOf(auth)); RequestBody verBody = RequestBody.create(MediaType.parse("text/plain"), String.valueOf(ver));
如果项目引入了Gson依赖,也可以用Gson做JSON转换:
Gson gson = new Gson(); String jsonStr = gson.toJson(num2); RequestBody delta = RequestBody.create(jsonMediaType, jsonStr);
3. 同步修改服务方法参数
把userUpload方法的参数类型和调用逻辑对应调整:
public void userUpload(String p, MultipartBody.Part image, RequestBody name, RequestBody fathername, RequestBody aadharnumber, RequestBody dob, RequestBody address, RequestBody gender, RequestBody plant, RequestBody cap, RequestBody aut, RequestBody ver, Response_listner response_listner) { Call<JsonObject> call = api_interface.upload(p, image, name, fathername, aadharnumber, dob, address, gender, plant,cap,aut,ver); serveCall(call, response_listner); }
调用时把之前传的布尔值auth、ver换成上面创建的authBody、verBody即可。
原理说明
Multipart协议上传时,每个分段都要声明自己的Content-Type,未指定类型时Retrofit默认使用text/plain普通文本类型,服务端会按字符串处理;指定application/json类型并传入合法的JSON字符串后,服务端就会自动将该分段解析为结构化的JSON对象。
内容的提问来源于stack exchange,提问作者Rahul Pandey
相关产品推荐
相关产品推荐

