项目需求:要求实现多张图片上传,并携带其他属性值。
项目使用框架:Rxjava+Retrofit+Okhttp。
先附上大神写的关于Retrofit的详细用法,本文所写以此文为基础:Retrofit详解。
分析后台接口,可以知道,我们需要以表单的形式上传,并且需要上传多张图片。
根据Retrofit注解知识可知,选用POST进行网络请求,请求体是一个Form表单,且需要支持多文件上传。
在Retrofit中表单请求分为两种标记FromURLEncoded和Multipart两类,前者与Field和FieldMap配合使用,后者与Part和PartMap配合使用;后者适合有文件上传的情况。
根据后台提供的接口,前端最后定义的上传接口如下:
@Multipart
@POST("visits/")
Observable> postVisitsInfo(@PartMap Map files) ;
拼装PartMap:
Map images = new HashMap();
//一般参数
images.put("visit_type", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, visit_type));
images.put("demand", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, demand));
images.put("dept_id", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, depart_id));
images.put("visitor_id", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, visitor_id+""));
images.put("expect_date", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, expect_time));
images.put("expert_name", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, expert));
images.put("hosp_id", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, hosp_id));
images.put("content", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, history));
//文件(注意与上面的不同)
if(imageFileList != null && !imageFileList.isEmpty()) {
for (File file:imageFileList){
images.put("files\";filename=\""+file.getName(), RequestBody.create(AppConstant.MEDIA_TYPE_JPG, file));
}
}
对上面的代码进行分析:
1、对于一般参数RequestBody只要指明参数类型即可。
2、对于多文件上传,不但要指明RequestBody的类型,还需要携带上“Content-Disposition请求头”,请求头中必须要有 filename=”xxx” 才会被当成文件,所以我们在写文件名的时候必须把 filename=”XXX” 也拼接上去,即文件名变成 “表单键名”; filename=”文件名“。此处是成功将文件上传的关键!
最后调用接口
mApiService.postVisitsInfo(images)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BaseSubscriber>(mContext, true, true) {
@Override
public void onNext(Response postVisitsRespModelResponse) {
setResult(RESULT_OK);
showToastMessage("订单提交成功");
OrderActivity.this.finish();
}
});
Luban.with(mContext)
.load(mSelectPath)
//质量小于100kb后不再进行压缩
.ignoreBy(100)
//压缩后的文件路径
.setTargetDir(FileUtils.createMkdirs(AppConstant.P_IMAGE))
.setCompressListener(new OnCompressListener() {
@Override
public void onStart() {
}
@Override
public void onSuccess(File file) {
//压缩成功后的处理逻辑
}
@Override
public void onError(Throwable e) {
Log.e("TAG", "Luban=" + e.getMessage());
}
}).launch();
Android上传多张图片的实例代码(RxJava异步分发)
Retrofit2.0 实现图文(参数+图片)上传方法总结
Android Retrofit 实现(图文上传)文字(参数)和多张图片一起上传