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

Android使用Retrofit 2携带Bearer令牌上传多图片+文本到服务器问题求助

修复方案

核心问题梳理

  • 上传接口未添加@Multipart注解,Retrofit无法识别多文件上传请求格式
  • Bearer令牌拼接不符合规范,缺少Bearer 前缀
  • 图片参数未封装为MultipartBody.Part类型,服务器无法识别为上传的文件资源
  • 未做空文件校验,路径无效时会直接触发崩溃

1. 修改接口类代码

// 新增@Multipart注解
@Multipart
@POST("invoices")
Call<ResponseBody> upload(
        @Header("Authorization") String authorization,
        // 图片参数改为MultipartBody.Part类型
        @Part MultipartBody.Part image1,
        @Part MultipartBody.Part image2,
        @Part MultipartBody.Part image3,
        @Part("invoice") RequestBody invoice
);

2. 修改上传逻辑代码

UserSharedPref sharedPref = new UserSharedPref(CompletedServiceActivity.this);
// 拼接Bearer令牌前缀,注意Bearer后面有一个空格
String token = "Bearer " + sharedPref.getUserToken();

// 封装图片为MultipartBody.Part,注意判断文件是否存在
MultipartBody.Part image1 = null;
if (patch_img1 != null && !patch_img1.isEmpty()) {
    File file1 = new File(patch_img1);
    if (file1.exists()) {
        RequestBody requestFile1 = RequestBody.create(MediaType.parse("image/*"), file1);
        // 第一个参数对应接口的字段名,第二个是文件名,第三个是文件RequestBody
        image1 = MultipartBody.Part.createFormData("image1", file1.getName(), requestFile1);
    }
}

// 同上封装image2、image3
MultipartBody.Part image2 = null;
if (patch_img2 != null && !patch_img2.isEmpty()) {
    File file2 = new File(patch_img2);
    if (file2.exists()) {
        RequestBody requestFile2 = RequestBody.create(MediaType.parse("image/*"), file2);
        image2 = MultipartBody.Part.createFormData("image2", file2.getName(), requestFile2);
    }
}

MultipartBody.Part image3 = null;
if (patch_img3 != null && !patch_img3.isEmpty()) {
    File file3 = new File(patch_img3);
    if (file3.exists()) {
        RequestBody requestFile3 = RequestBody.create(MediaType.parse("image/*"), file3);
        image3 = MultipartBody.Part.createFormData("image3", file3.getName(), requestFile3);
    }
}

RequestBody invoice = RequestBody.create(MediaType.parse("text/plain"), invoices);

WebServicesAPI request = APIClient.getApiClient("https://text.com/api/").create(WebServicesAPI.class);
Call<ResponseBody> call = request.upload(token, image1, image2, image3, invoice);

call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        // 这里可以打印response.code()和response.errorBody(),排查服务端返回的错误信息
        if (response.isSuccessful()) {
            // 上传成功逻辑
        } else {
            // 服务端返回错误,打印错误内容排查问题
            try {
                Log.e("UploadError", response.errorBody().string());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 网络错误、本地错误排查,打印堆栈
        t.printStackTrace();
    }
});

3. 可选优化(APIClient类增加超时配置)

当前的APIClient没有配置超时时间,上传大文件容易触发超时,可修改如下:

public class APIClient {
    public static Retrofit retrofit = null;
    public static Retrofit getApiClient(String url) {
        if (retrofit == null) {
            // 配置OkHttpClient超时时间
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .build();

            Gson gson = new GsonBuilder()
                    .setLenient()
                    .create();
            retrofit = new Retrofit.Builder()
                    .baseUrl(url)
                    .client(client) // 注入自定义的OkHttpClient
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();
        }
        return retrofit;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 16:45:03