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

使用Retrofit 2.1.0发送Multipart图片时出现Bad Request错误

解决Retrofit 2.1.0 Multipart上传图片的Bad Request问题

看起来你在使用Retrofit 2.1.0以Multipart形式上传图片时遇到了Bad Request错误,我来帮你排查可能的问题并给出修复方案:

可能的问题点及修复步骤

1. 媒体类型(MediaType)不够明确

你当前使用的是MediaType.parse("image/*"),部分服务器可能不接受通配符类型,需要指定具体的图片格式(比如JPEG、PNG)。建议根据文件的后缀名来设置对应的MediaType:

// 获取文件后缀名,判断图片类型
String extension = MimeTypeMap.getFileExtensionFromUrl(savedpath);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (mimeType == null) {
    // 默认设置为jpeg
    mimeType = "image/jpeg";
}
RequestBody requestFile = RequestBody.create(MediaType.parse(mimeType), file);

2. 检查文件是否存在及权限

Bad Request也可能是因为文件不存在或者应用没有读取文件的权限。在创建File对象后,先添加检查:

File file = new File(savedpath);
if (!file.exists() || !file.isFile()) {
    Toast.makeText(DetailActiveSRActivity.this, "文件不存在或无效", Toast.LENGTH_SHORT).show();
    hideLoader();
    return;
}
// 另外,确保你已经申请了读取外部存储的权限(Android 6.0及以上需要动态申请)

3. 核对接口参数与服务器要求

  • 确认服务器端接收图片的参数名是否是"image",你的代码里用的是createFormData("image", file.getName(), requestFile),如果服务器要求的参数名不同(比如"file"),就会导致错误。
  • 检查userId的参数名是否正确,你的接口里是@Part("userId") RequestBody userId,确保服务器端接收的参数名一致。
  • 检查Header中的authkey是否正确,你设置的是ABCD@123,确认这个值和服务器要求的匹配。

4. 额外排查技巧

在onResponse中打印服务器返回的错误详情,能帮你快速定位问题:

if (!response.isSuccessful()) {
    Log.e(TAG, "onResponse: Error code " + response.code() + ", message: " + response.message());
    try {
        Log.e(TAG, "Error body: " + response.errorBody().string());
    } catch (IOException e) {
        e.printStackTrace();
    }
    Toast.makeText(DetailActiveSRActivity.this, "请求失败:" + response.message(), Toast.LENGTH_SHORT).show();
    return;
}

修改后的完整代码示例

private void saveImageToServer(final String savedpath) {
    showLoader();
    NetworkUtil.checkInternetConnection(DetailActiveSRActivity.this, new NetworkUtil.NetworkStatusListener() {
        @Override
        public void onNetworkAvailable() {
            File file = new File(savedpath);
            // 检查文件有效性
            if (!file.exists() || !file.isFile()) {
                Toast.makeText(DetailActiveSRActivity.this, "文件不存在或无效", Toast.LENGTH_SHORT).show();
                hideLoader();
                return;
            }

            // 获取正确的媒体类型
            String extension = MimeTypeMap.getFileExtensionFromUrl(savedpath);
            String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
            if (mimeType == null) {
                mimeType = "image/jpeg";
            }
            RequestBody requestFile = RequestBody.create(MediaType.parse(mimeType), file);
            Log.e(TAG, "onNetworkAvailable: requestFIle " + savedpath+"\n"+" file "+file);

            MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
            Log.e(TAG, "onNetworkAvailable: body " + body);

            RequestBody reqUserId = RequestBody.create(MediaType.parse("text/plain"), userId);
            //RequestBody reqImageType =RequestBody.create(MediaType.parse("text/plain"), "1");

            Call<SaveImageResponseModel> responseCall = mService.saveImages(body, reqUserId);
            responseCall.enqueue(new Callback<SaveImageResponseModel>() {
                @Override
                public void onResponse(Call<SaveImageResponseModel> call, retrofit2.Response<SaveImageResponseModel> response) {
                    hideLoader();
                    // 打印错误详情
                    if (!response.isSuccessful()) {
                        Log.e(TAG, "onResponse: Error code " + response.code() + ", message: " + response.message());
                        try {
                            Log.e(TAG, "Error body: " + response.errorBody().string());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        Toast.makeText(DetailActiveSRActivity.this, "请求失败:" + response.message(), Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (response != null) {
                        SaveImageResponseModel apiResponse = response.body();
                        if (apiResponse != null && apiResponse.getStatus()) {
                            Log.e(TAG, "onRequestSuccess: " + apiResponse);
                        } else {
                            Toast.makeText(DetailActiveSRActivity.this, getString(R.string.noDataError), Toast.LENGTH_SHORT).show();
                        }
                    } else {
                        Toast.makeText(DetailActiveSRActivity.this, getString(R.string.noDataError), Toast.LENGTH_SHORT).show();
                    }
                }

                @Override
                public void onFailure(Call<SaveImageResponseModel> call, Throwable t) {
                    hideLoader();
                    Log.e(TAG, "onFailure: ", t);
                    Toast.makeText(DetailActiveSRActivity.this, "请求失败:" + t.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
        }

        @Override
        public void onNetworkNotAvailable() {
            Toast.makeText(DetailActiveSRActivity.this, getString(R.string.noNetworkMessage), Toast.LENGTH_SHORT).show();
            hideLoader();
        }
    });
}

// 接口部分保持不变,确认参数名与服务器匹配即可
@Headers({ "authkey: ABCD@123" })
@Multipart
@POST(UrlUtils.POST_IMAGES)
Call<SaveImageResponseModel> saveImages(@Part MultipartBody.Part file, @Part("userId") RequestBody userId);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:16:58