Retrofit 上传多文件几种方式

本文详细介绍了使用Retrofit进行多文件上传的方法,包括MultipartBody.Part和RequestBody的使用,展示了如何将Map转换为RequestBody和MultipartBody.Part,以及同步和异步请求的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Retrofit 上传多文件方式:
一 .Multipart & MultipartBody.Part:
Api Service:
//上传多个文件.单文件就把List去掉
@Multipart
@POST(WX_URL)
Call<ResponseBody> uploadGatherInfo(@PartMap Map<String, RequestBody> params, 
@Part List<MultipartBody.Part>  files);

params :额外的属性参数

files:文件参数

注解PartMap对应的Map(这里指params)的value有2种方式处理

1.如果value的类型是okhttp3.RequestBody RequestBody,该值将与它的内容类型直接使用。

2.其他对象类型将通过使用 Converter 转换为适当的表示形式。

Send Request:
Map<String, RequestBody> bodyMap = RetrofitTransUtil.map2RequestBody(transParams);
List<MultipartBody.Part> multipart = RetrofitTransUtil.map2Multipart(fileParams);
 if (multipart == null) {
      Log.d("Trans File","文件不存在");
      return;
    }
//同步
Response<ResponseBody> response = RequestService.getWxService().
                    uploadGatherInfo(bodyMap, multipart).execute();
//异步
RequestService.getWxService().
                    uploadGatherInfo(bodyMap, multipart).enqueue(...);

因为封装传的额外参数是Map<String, Object> transParams ,要把transParams转换成Map<String,RequestBody>

传的File参数是Map<String,String> fileParams ,要把fileParams转换成 List<MultipartBody.Part>

public class RetrofitTransUtil {

    public static  MultipartBody.Part file2Part(File file){
        return file2Part("file",file);
    }

    public static  MultipartBody.Part file2Part(String name,File file){
        RequestBody bodySingle = RequestBody.create(MultipartBody.FORM,file);
        final   MultipartBody.Part bodyPart = MultipartBody.Part.createFormData(
                name, file.getName(),bodySingle);
        return bodyPart;
    }

    public static RequestBody string2RequestBody(String param){
        RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), param);
        return requestBody;
    }
    public static  Map<String,RequestBody> map2RequestBody(Map<String,Object> params){
        Map<String,RequestBody> map = new HashMap<String, RequestBody>();
        if (params!= null && !params.isEmpty()) {
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                if (entry.getValue() != null) {
                    if (entry.getValue() instanceof String) {
                        map.put(entry.getKey(), RetrofitTransUtil.
                                string2RequestBody(String.valueOf(entry.getValue())));
                    }
                        /*if (entry.getValue() instanceof File) {
                            File f = (File) entry.getValue();
                            builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
                        } else {
                            builder.addFormDataPart(entry.getKey(), entry.getValue().toString());
                        }*/
                }
            }
        }
        return map;
    }


    public static List<MultipartBody.Part> map2Multipart(Map<String,String> params) {
        List<MultipartBody.Part> parts = new ArrayList<>();
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                if (entry.getValue() != null && entry.getValue().length() != 0) {
                    File file = new File(entry.getValue());
                    if (file.exists()) {
                        parts.add(file2Part(entry.getKey(), file));
                    }else{
                        return  null;
                    }
                        /*if (entry.getValue() instanceof File) {
                            File f = (File) entry.getValue();
                            builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
                        } else {
                            builder.addFormDataPart(entry.getKey(), entry.getValue().toString());
                        }*/
                }
            }
        }
        return parts;
    }
二 .Multipart & RequestBody:
//上传文件
@Multipart
@POST("upload")
Call<String> uploadFile(@Part("file") RequestBody file);

注解Part对应参数类型以下三种方式之一处理:

1.如果类型是MultipartBody.Part,内容将直接使用。从注解中省略名称(例如,@Part MultipartBody.Part part})。2.如果类型是okhttp3.RequestBody RequestBody,该值将与它的内容类型直接使用。在注解中提供part名称(例如,@Part(“foo”) RequestBody foo)

3.其他对象类型将通过使用 Converter转换为合适的表示形式。在注解中提供Part名称(例如,* {@code @Part(“foo”) Image photo})

RequestBody bodySingle = RequestBody.create(MultipartBody.FORM,file);

RequestBody body = RequestBody.create(MediaType.parse(“image/jpeg”),file)

当然你也可以用@PartMap Map<String,RequestBody> map 来上传多个文件,不过要拼接Form参数 “file”; filename=""+ your file name 作为key, RequestBody作为value

参考:https://blog.youkuaiyun.com/Cricket_7/article/details/89668235
https://www.jianshu.com/p/74b7da380855

三:Body
    @POST("/upload.php")
    public Call<String> upload(@Body RequestBody file);

这种方式函数不可以使用@Multipart注解和@FormUrlEncoded注解,并且@Body注解只能使用一次,函数的参数类型没有要求,只要可以通过Convert转换成RequestBody就行,不过上传文件一般用直接用RequestBody。如果使用MultipartBody类型作为参数,一定要设置type为MultipartBody.FORM

参考:https://www.jianshu.com/p/e1012490c886
https://www.jianshu.com/p/acfefb0a204f

这种方法,我没有用过O(∩_∩)O

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值