使用Retrofit2 RxJava 文件上传

前言

Retrofit2 的文件上传在官方网站上并没有多说,只是说可以使用@Multipart注解即可使用,但是没有细致的去讲解这块怎么用。
在github的issus上有几篇文章,讲的有点乱,现在整理一下,如何使用Retrofit2 和 RxJava 来实现文件上传。

单文件上传

Server配置

    @POST("/file")
    @Multipart
    Observable> uploadFile(@Part("file\"; filename=\"avatar.png\"") RequestBody file);

此处@Part(“file\”; filename=\”avatar.png\”“)注释的含义是该RequestBody 的名称为file,上传的文件名称为avatar.png。
@Path注解中的filename与上传文件的真实名称可以不匹配

RxJava调用

rxjava

public void uploadFiles(File file){
    //代理模式生成对应server的实例化对象
    FileUploadServer server = getRetrofit().create(FileUploadServer.class);
    //创建RequwstBody对象
    RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
    //使用RxJava方式调度任务并监听
    server.uploadFile(requestBody)
          .observeOn(AndroidSchedulers.mainThread())
          .subscribeOn(Schedulers.io())
           .map(new ResponseFunc())
           .subscribe(new Subscriber() {
               @Override
               public void onCompleted() {

               }

               @Override
               public void onError(Throwable e) {
                   DebugLog.wtf("upload error" + e.getMessage());
               }

               @Override
               public void onNext(UploadFile uploadFile) {
                   DebugLog.wtf("upload Success" + uploadFile.uploadFileName());
               }
           });
}

多文件上传

Server配置

@Multipart
@POST("/files")
Call uploadFiles(@PartMap Map params);

此处使用@PartMap注释,传递多个Part,以实现多文件上传。

RxJava调用

rxjava

public void uploadFiles(File... files){
    //代理模式生成对应server的实例化对象
    FileUploadServer server = getRetrofit().create(FileUploadServer.class);
    //组装partMap对象
    Map partMap = new HashMap<>();
    for(File file : files ){
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
        partMap.put("file\"; filename=\""+file.getName()+"\"", fileBody);
    }
    //使用RxJava方式调度任务并监听
    server.uploadFiles(partMap)
          .observeOn(AndroidSchedulers.mainThread())
          .subscribeOn(Schedulers.io())
           .map(new ResponseFunc())
           .subscribe(new Subscriber() {
               @Override
               public void onCompleted() {

               }

               @Override
               public void onError(Throwable e) {
                   DebugLog.wtf("upload error" + e.getMessage());
               }

               @Override
               public void onNext(UploadFile uploadFile) {
                   DebugLog.wtf("upload Success" + uploadFile.uploadFileName());
               }
           });
}

关键还是在于partMap.put(“file\”; filename=\”“+file.getName()+”\”“, fileBody);此处的key就充当了单文件上传时@Part中设置的参数。

混合上传

现实使用中,一般会有一种需求是,传文件的同时需要上传一些其他的字段,这怎么办?

改造自单文件上传的代码

Server

    @POST("/file")
    @Multipart
    Observable> uploadFile(@Part("file\"; filename=\"avatar.png\"") RequestBody file,@Part("nickName") RequestBody nickName);

RxJava调用

rxjava

public void uploadFiles(File file,String nickName){
    //代理模式生成对应server的实例化对象
    FileUploadServer server = getRetrofit().create(FileUploadServer.class);
    //创建RequwstBody对象
    RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
    //创建nickNameBody对象
    RequestBody nickNameBody = RequestBody.create(MediaType.parse("text/plain"), nickName);
    //使用RxJava方式调度任务并监听
    server.uploadFile(requestBody,nickNameBody)
          .observeOn(AndroidSchedulers.mainThread())
          .subscribeOn(Schedulers.io())
           .map(new ResponseFunc())
           .subscribe(new Subscriber() {
               @Override
               public void onCompleted() {

               }

               @Override
               public void onError(Throwable e) {
                   DebugLog.wtf("upload error" + e.getMessage());
               }

               @Override
               public void onNext(UploadFile uploadFile) {
                   DebugLog.wtf("upload Success" + uploadFile.uploadFileName());
               }
           });
}

其实就是增加了一个@Part,只不过该Part是一个text/plain多媒体类型的。

改造自多文件上传的代码

Server配置不变

RxJava调用

rxjava

public void uploadFiles(File... files){
    //代理模式生成对应server的实例化对象
    FileUploadServer server = getRetrofit().create(FileUploadServer.class);
    //组装partMap对象
    Map partMap = new HashMap<>();
    for(File file : files ){
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
        partMap.put("file\"; filename=\""+file.getName()+"\"", fileBody);
    }
        RequestBody nickNameBody = RequestBody.create(MediaType.parse("text/plain"), nickName);
        partMap.put("nickName" , nickNameBody);
    //使用RxJava方式调度任务并监听
    server.uploadFiles(partMap)
          .observeOn(AndroidSchedulers.mainThread())
          .subscribeOn(Schedulers.io())
           .map(new ResponseFunc())
           .subscribe(new Subscriber() {
               @Override
               public void onCompleted() {

               }

               @Override
               public void onError(Throwable e) {
                   DebugLog.wtf("upload error" + e.getMessage());
               }

               @Override
               public void onNext(UploadFile uploadFile) {
                   DebugLog.wtf("upload Success" + uploadFile.uploadFileName());
               }
           });
}

其实只是在partMap中put了一个RequestBody。
partMap.put(“nickName” , nickNameBody);

UploadFile.java

public class UploadFile {
    private String fid;
    private String sourceFileName;
    private String uploadFileName;

    public String getFid() {
        return fid;
    }

    public void setFid(String fid) {
        this.fid = fid;
    }

    public String getSourceFileName() {
        return fileName;
    }

    public void setSourceFileName(String sourceFileName) {
        this.sourceFileName = sourceFileName;
    }

    public String getUploadFileName() {
        return uploadFileName;
    }

    public void setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
    }
}

你可能感兴趣的:(Android)