1、今天终于实现了retrifit+RxJava的多文件上传,这个东西真的困住了我挺长时间的了。因为要结合后台已经写好的java代码,只能一遍遍找代码,也有自己刚刚接触retrifit的关系吧。
2、首先Android代码是基于https://blog.csdn.net/wzgiceman/article/details/51939574这个的封装进行实现的,所以需要结合这个一起参考才能实现
3、首先看一下java后台代码,后台代码是根据mybatis框架写的,其中需要配置文件的接收方式。这里就不细说了。Java端是可以接收对象和文件数组的。
@RequestMapping(value = "/uploadFileTest", method = RequestMethod.POST)
@ResponseBody
private Result uploadFileTest(@RequestParam("files") MultipartFile[] files,User user) {
Result result = new Result();
try {
String path = PropertiesUtils.propertiesMap.get("upload.path");
String dirName = "order";
File dir = new File(path + "/" + dirName);
if (!dir.exists()) {
dir.mkdirs();
}
for(int i=0;i<files.length;i++){
MultipartFile multipartFile = files[i];
String name=multipartFile.getOriginalFilename();
long b=multipartFile.getSize();
String filename = Utils.getUUID() + ".png";
File filepath = new File(dir.getPath(), filename);
multipartFile.transferTo(filepath);
}
} catch (Exception e) {
logger.error("文件上传测试接口====", e);
}
return result;
}
4、那么继续来看Android端代码:
(1)、首先需要创建一个接口:files我这里定义的是数组,也可以定义成集合。
@Multipart
@POST("user/uploadFileTest")
Observable<String> uploadFiles(@Part() MultipartBody.Part[] files,@PartMap Map<String , RequestBody> usermaps);
(2)、写一个对接口的赋值方法:
public class UploadFileList extends BaseApi {
/*需要上传的文件*/
//private MultipartBody.Part part;
private MultipartBody.Part[] parts;
private Map<String , RequestBody> userList;
public UploadFileList() {
setShowProgress(true);
setMethod("user/uploadFileTest");
setCache(false);
}
public MultipartBody.Part[] getParts() {
return parts;
}
public void setParts(MultipartBody.Part[] parts) {
this.parts = parts;
}
public Map<String, RequestBody> getUserList() {
return userList;
}
public void setUserList(Map<String, RequestBody> userList) {
this.userList = userList;
}
@Override
public Observable getObservable(Retrofit retrofit) {
HttpUploadService httpService = retrofit.create(HttpUploadService.class);
return httpService.uploadFiles(parts,userList);
}
}
(3)、让我们来看一下Activity的代码:
private void uploadFileMethod(List<File> files){
Map<String,RequestBody> imgs = new HashMap<>();
HttpManager manager = new HttpManager(this, this);
RequestBody requestBody=null;
for (int i=0;i<files.size();i++) {
requestBody = RequestBody.create(MediaType.parse("image/png"),files.get(i));
imgs.put(files.get(i).getName(),requestBody);
}
uploadList=new UploadFileList();
uploadList.setParts(filesToMultipartBodyParts(files));
RequestBody tokenBody = RequestBody.create(MediaType.parse("multipart/form-data"), "1");
HashMap<String, RequestBody> map = new HashMap<>(); map.put("userId", tokenBody);
uploadList.setUserList(map);
manager.doHttpDeal(uploadList);
}
public static MultipartBody.Part[] filesToMultipartBodyParts(List<File> files) {
MultipartBody.Part[] parts = new MultipartBody.Part[files.size()];
for(int i=0;i<files.size();i++){
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), files.get(i));
MultipartBody.Part part = MultipartBody.Part.createFormData("files", files.get(i).getName(), requestBody);
parts[i]=part;
}
return parts;
}
5、好了,大功告成;其中在写的时候,我后台一直没有接收到值,一直以为是我写的Android方法有问题,后来才发现想,下面代码中的files才是Java端接收到的值。命名必须和Java端的@RequestParam("files") MultipartFile[] files一致。这个坑好深,也是自己查了好多资料,确定代码都没问题才慢慢发现的。
MultipartBody.Part.createFormData("files", files.get(i).getName(), requestBody);,
6、具体图片如下:
7、再记录一下Get方式获得数据传值的接口:
@GET("syncUser!getAppsData.do")
Observable<String> getApps(@Query("updateTime") String updateTime);
8、和Post方式传递多条数据以Json进行上传的方法:
@FormUrlEncoded
@POST("syncUser!uploadUserData.do")
Observable<String> uploadUser(@Field("userList") String userList);