天天看点

Retrofit学习之文件和参数上传

参数上传

1. 参数个数不是很多时

@FormUrlEncoded
@POST("upload")
Call<ResponseBody> uploadParams(@Field("username")String username,@Field("token")String token);
           

使用直接传入参数值即可

2. 多个参数上传

@FormUrlEncoded
@POST("upload")
Call<ResponseBody> uploadParams(@FieldMap Map<String,String> map);   
           

调用的时候,直接传入一个map集合,即可

3. 通用的方法

@POST("upload")
Call<ResponseBody> uploadParams(@Body RequestBody body);
           

调用时,传入一个

RequestBody

对象,OkHttp库中有一个专门用来构建参数上传的

RequestBody

子类,即

FormBody

,如下

FormBody body=new FormBody.Builder()
                .add("username","admin")
                .add("token","sjdkdjows=dmzkkshf")
                .build();
           

在使用的时候,直接调用

uploadParams (body)

即可实现上传。

文件上传

1. 单个文件上传

@Multipart
 @POST("upload")
Call<ResponseBody> uploadOneFile(@Part MultipartBody.Part body);
           

调用的使用

MultipartBody.Part

来构造一个Part对象参数

String name = etFileName.getText().toString().trim();
name = TextUtils.isEmpty(name) ? "1.png" : name;
String path = Environment.getExternalStorageDirectory() + File.separator + name;
File file = new File(path);

RequestBody fileRQ = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part part MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);

Call<ResponseBody> uploadCall = downloadService.uploadOneFile(part);
           

2. 多文件上传

使用

@PartMap

实现

@Multipart
@POST("upload")
Call<ResponseBody> uploadFiles(@PartMap Map<String, RequestBody> map);
           

调用方法

RequestBody fb = RequestBody.create(MediaType.parse("text/plain"), "hello,retrofit");
RequestBody fileTwo = RequestBody.create(MediaType.parse("image/*"), new File(Environment.getExternalStorageDirectory()
                + file.separator + "original.png"));
Map<String, RequestBody> map = new HashMap<>();
//这里的key必须这么写,否则服务端无法识别
map.put("file\"; filename=\""+ file.getName(), fileRQ);
map.put("file\"; filename=\""+ "2.png", fileTwo);

Call<ResponseBody> uploadCall = downloadService.uploadFiles(map);
           

使用

@Part

实现

@Multipart
@POST("upload")
Call<ResponseBody> uploadFiles(@Part List<MultipartBody.Part> parts);

           

调用代码如下:

RequestBody fileRQ = RequestBody.create(MediaType.parse("image/*"), file);

MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);

RequestBody fb = RequestBody.create(MediaType.parse("text/plain"), "hello,retrofit");
RequestBody fileTwo = RequestBody.create(MediaType.parse("image/*"), new File(Environment.getExternalStorageDirectory()
                + file.separator + "original.png"));
MultipartBody.Part two=MultipartBody.Part.createFormData("one","one.png",fileTwo);
List<MultipartBody.Part> parts=new ArrayList<>();
parts.add(part);
parts.add(two);

 Call<ResponseBody> uploadCall = downloadService.uploadFiles(parts);
           

文件和参数混合上传

@Multipart
@POST("upload")
Call<ResponseBody> uploadFile(@Part("body") RequestBody body, @Part MultipartBody.Part file);
           
MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);
RequestBody fb =RequestBody.create(MediaType.parse("text/plain"), "hello,retrofit");
Call<ResponseBody> uploadCall = downloadService.uploadFile(fb,part);
           

通用上传方式

接口定义,注意这个时候没有

@Multipart

@POST("upload")
 Call<ResponseBody> uploadFile(@Body RequestBody body);
           

利用

MultipartBody

来实现通用的参数和文件上传

String name = etFileName.getText().toString().trim();
        name = TextUtils.isEmpty(name) ? "1.png" : name;
        String path = Environment.getExternalStorageDirectory() + File.separator + name;
        File file = new File(path);
        RequestBody fileRQ = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);

        RequestBody body=new MultipartBody.Builder()
                .addFormDataPart("userName","lange")
                .addFormDataPart("token","dxjdkdjkj9203kdckje0")
                .addFormDataPart("header",file.getName(),fileRQ)
                .build();
        Call<ResponseBody> uploadCall = downloadService.uploadFile(body);
        uploadCall.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Log.i("upload", response.isSuccessful() + "");
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {

            }
        });
           

看下服务端的输出:

userName-->lange
token-->dxjdkdjkj9203kdckje0
/Users/lange/Desktop/web/out/artifacts/web_war_exploded/upload/1.png
           
当我们采用这种方式上传的时候,不能再接口上加上

@Multipart

的注解,否者会报错

注意:

  1. 如果在上传文件的时候,定义:
@Multipart
@POST("upload")
Call<ResponseBody> uploadOneFile(@Part RequestBody file);
           

显示下面的错误:

@Part annotation must supply a name or use MultipartBody.Part parameter type. (parameter #1)
           
  1. 如果@Part加上参数,并RequestBody作为参数,上传文件,服务端识别不出来这是一个文件,会当做一个参数上传的例子
@Multipart
@POST("upload")
Call<ResponseBody> uploadOneFile(@Part("file") RequestBody file);
           
  1. 如果使用MultipartBody.Part作为参数,又加上了名字
uploadOneFile(@Part("file") MultipartBody.Part file)
           

则会显示下面的错误

@Part parameters using the MultipartBody.Part must not include a part name in the annotation
           

作者:lange0x0

链接:https://www.jianshu.com/p/74b7da380855

来源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

继续阅读