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);
7、和Post方式传递多条数据以Json进行上传的方法:
@FormUrlEncoded @POST("syncUser!uploadUserData.do") Observable<String> uploadUser(@Field("userList") String userList);