Android Retrofit 2.3.0多图上传报400 Bad Request错误排查求助
我帮你梳理了代码里的几个关键问题,这些大概率是导致400错误的原因,咱们一步步来修正:
1. 路径参数与@Part注解冲突(核心问题)
你的@POST接口URL里包含了{memberId}和{actionType}两个路径占位符,但你在方法参数里却用@Part来传递这两个值——这会导致Retrofit无法正确替换路径里的占位符,服务器收到的请求路径是不完整的(比如还是带着{memberId}这种占位符),直接触发400错误。
修正接口定义
把这两个参数的注解从@Part改成@Path,并且直接用String类型传递(更符合路径参数的使用场景):
@Multipart @POST("/api/mbrphotos/prfImgIU/{memberId}/{actionType}") Call<JsonObject> postImages( @Path("memberId") String memberId, @Path("actionType") String actionType, @Part MultipartBody.Part[] multipartTypedOutput );
修正调用代码
不用再创建RequestBody,直接传字符串即可:
String memberId = Singleton.getInstance().getUserRegDetailsRespModel().getMId(); String actionType = ACTION_TYPE_UPLOAD_NEW_PIC; Call<JsonObject> stringCall = mServerUtilities.getStringClassService(getApplicationContext(), "").postImages(memberId, actionType, multipartTypedOutputle);
2. 文件字段名与服务器期望不匹配
你创建MultipartBody.Part时用的字段名是"imageFiles["+index+"]",但你的multiImagesList里存的是originalImgBlob、img430Blog这些自定义字段名。如果服务器期望接收的是这些特定命名的文件参数(而非数组形式的imageFiles[0]),那当前的字段名完全不符合要求,服务器找不到对应参数也会返回400。
修正字段名设置
把FormData的name改成multiImagesList里存储的自定义字段名,同时用真实文件名作为文件名参数:
for (int index = 0; index < mFiles.size(); index++) { Log.d("Upload request", "requestUploadSurvey: survey image " + index + " " + mFiles.get(index)); // 根据文件实际类型获取MIME类型,避免固定为png File file = mFiles.get(index); String mimeType = Files.probeContentType(file.toPath()); if (mimeType == null) { mimeType = "image/*"; // 兜底处理 } RequestBody surveyBody = RequestBody.create(MediaType.parse(mimeType), file); // 使用自定义字段名作为FormData的name multipartTypedOutputle[index] = MultipartBody.Part.createFormData( multiImagesList.get(index).getFileName(), file.getName(), // 传递真实文件名 surveyBody ); }
3. 固定MediaType可能导致的类型不匹配
你之前固定用MediaType.parse("image/png"),如果上传的文件是JPG或其他格式,会导致Content-Type不正确,可能被服务器拒绝。上面的代码已经改成了根据文件实际类型获取MIME类型,解决了这个问题。
先优先解决路径参数的问题,这是最致命的错误,之后再根据服务器文档确认文件字段名是否正确,应该就能解决400错误了。
内容的提问来源于stack exchange,提问作者uma

