使用PartMap Retrofit 2上传多个文件

8

当发布一个新产品时,我的服务器需要捕捉带有密钥的文件。文件数量没有限制,文件是无限的。

使用Retrofit 1.9时,一切都进行得很完美。但是在我更新到Retrofit 2之后,我的服务器就收不到任何文件了。

如果我修改服务器,就不能再向后兼容了。我需要让Android应用程序像使用Retrofit 1.9时那样工作。

以下是我的实现方式。

Retrofit 1.9

创建ApiService接口的类。

public class ApiClient {

    public interface ApiInterface {

        @Multipart
        @POST("/products/")
        void uploadProduct(
                @PartMap Map<String, String> params,
                @PartMap Map<String, TypedFile> files,
                Callback<Product> cb);

    }

}

使用ApiService。

Map<String, String> params = new HashMap<>();
params.put("title", title);
params.put("price", price);
params.put("content", content);

Map<String, TypedFile> files = new HashMap<>();
for (int pos = 0; pos < photoPaths.length; pos++) {
    if (!Strings.isNullOrEmpty(photoPaths[pos])) {
        TypedFile typedFile = new TypedFile("multipart/form-data", new File(photoPaths[pos]));
        files.put("photo_" + String.valueOf(pos + 1), typedFile);
    }
}

apiInterface.uploadProduct(params, files, cb);

Retrofit 2

用于创建ApiService接口的类。

public class ApiClient {

    public interface ApiInterface {

        @Multipart
        @POST("/products/")
        Call<Product> uploadProduct(
                @PartMap Map<String, RequestBody> params,
                @PartMap Map<String, RequestBody> files);


    }

    public static final String MULTIPART_FORM_DATA = "multipart/form-data";

    public static RequestBody createRequestBody(@NonNull File file) {
        return RequestBody.create(
                MediaType.parse(MULTIPART_FORM_DATA), file);
    }

    public static RequestBody createRequestBody(@NonNull String s) {
        return RequestBody.create(
                MediaType.parse(MULTIPART_FORM_DATA), s);
    }

}

使用ApiService

Map<String, RequestBody> params = new HashMap<>();
params.put("title", ApiClient.createRequestBody(title));
params.put("price", ApiClient.createRequestBody(price));
params.put("content", ApiClient.createRequestBody(content));

Map<String, RequestBody> files = new HashMap<>();
for (int pos = 0; pos < photoPaths.length; pos++) {
    if (!TextUtils.isEmpty(photoPaths[pos])) {
        RequestBody requestBody = ApiClient.createRequestBody(new File(photoPaths[pos]));
        files.put("photo_" + String.valueOf(pos + 1), requestBody);
    }
}

Call<Product> call = apiInterface.uploadProduct(params, files);

你能发布你的打字文件吗? - Vishal Yadav
文件是图像文件,如png、jpg,没有什么特别的。 - Aung Thiha
1
我也遇到了同样的问题... 我想在“单个”键中发布多张图片。 - Vishal Yadav
1个回答

6

我采用了 这个解决方案,现在问题已经解决。

这是我的实现方法。

Map<String, RequestBody> params = new HashMap<>();
params.put("title", ApiClient.createRequestBody(title));
params.put("price", ApiClient.createRequestBody(price));
params.put("content", ApiClient.createRequestBody(content));

Map<String, RequestBody> files = new HashMap<>();
for (int pos = 0; pos < photoPaths.length; pos++) {
    if (!TextUtils.isEmpty(photoPaths[pos])) {
        RequestBody requestBody = ApiClient.createRequestBody(new File(photoPaths[pos]));
        // fix is right here
        String key = String.format("%1$s\"; filename=\"%1$s", "photo_" + String.valueOf(pos + 1));
        files.put(key, requestBody);
    }
}

Call<Product> call = apiInterface.uploadProduct(params, files);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接