使用Retrofit2 RxJava 文件上传

来源:互联网 发布:家庭资产负债表 知乎 编辑:程序博客网 时间:2024/05/16 17:44

前言

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

单文件上传

Server配置

    @POST("/file")    @Multipart    Observable<DataResponse<UploadFile>> 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<UploadFile>())           .subscribe(new Subscriber<UploadFile>() {               @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<UploadInformationTransfer> uploadFiles(@PartMap Map<String, RequestBody> params);

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

RxJava调用

rxjava

public void uploadFiles(File... files){    //代理模式生成对应server的实例化对象    FileUploadServer server = getRetrofit().create(FileUploadServer.class);    //组装partMap对象    Map<String, RequestBody> 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<UploadFile>())           .subscribe(new Subscriber<UploadFile>() {               @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<DataResponse<UploadFile>> 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<UploadFile>())           .subscribe(new Subscriber<UploadFile>() {               @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<String, RequestBody> 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<UploadFile>())           .subscribe(new Subscriber<UploadFile>() {               @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;    }}
0 1
原创粉丝点击