上一篇中我将我使用的基本的引用已经粘贴如果你对于引用出现的问题的话可以直接复制使用。由于最近使用文件上传的时候如果去使用retrofit+rxjava比较迷茫吧。所以查找了一些资料,自己也进行测试。就自己使用的两种拿出来分享一下首先第一种方式是一对多的形式:就是只需要一个key可以传递多个value也就是多个文件,第二种形式是一对一的形式。就是键值对形式封装的形式也是map。解决多组图片上传同时键(key)不一样的情况。展示第一种上传文件的代码样式:
/** * 改进模式 * 模式同上,改进原因同上 */ @Multipart @POST() Observable<BaseBean> requestUploadWork(@Url String url, @PartMap Map<String, RequestBody> params, @Part List<MultipartBody.Part> parts);
这种为第一种形式。url表示子路径可以动态的改变路径,在上传文件的时候需要用到@part或@partMap注解如果还没有了解注解的,下面的网址可以了解注解的使用以及限定条件避免使用错误。无法请求到数据,https://www.jianshu.com/p/bf884248cb37https://www.jianshu.com/p/7c907686f6c5可以看到传递的文件集合为MultipartBody.Part因此需要将你的文件封装成这个格式下面代码就是对数据的封装
public class RequestBodyUtil { /** * 将文件路径数组封装为{@link List<MultipartBody.Part>} * * @param key 对应请求正文中name的值。目前服务器给出的接口中,所有图片文件使用<br> * 同一个name值,实际情况中有可能需要多个 */ public static List<MultipartBody.Part> filesToMultipartBodyParts(List<File> files, String key) { List<MultipartBody.Part> parts = new ArrayList<>(files.size()); for (File file : files) { RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file); MultipartBody.Part part = MultipartBody.Part.createFormData(key, file.getName(), requestBody); parts.add(part); } return parts; } /** * 将参数封装成requestBody形式上传参数 * @param param 参数 * @return RequestBody */ public static RequestBody convertToRequestBody(String param){ RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), param); return requestBody; } /** * 将文件进行转换 * @param param 为文件类型 * @return */ public static RequestBody convertToRequestBodyMap(File param){ RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), param); return requestBody; } }
使用的过程中仅仅需要这样调用
List<MultipartBody.Part> parts = RequestBodyUtil.filesToMultipartBodyParts(files, key);就可以将你的文件和键封装起来然后调用响应的接口就可以了,同时@PartMap Map<String, RequestBody> params,为传递的文本参数,因为我们调用接口的时候不可能只传递照片文件还要传递一下文本参数,因此params用来保存文本参数,String对应你传递的字段key,requestBody对应你的值,因此还需对你传递的数据转换为requestBody,调用RequestBodyUtil .convertToRequestBody方法就可以将字符串转换为requestBody.如果你对转换的方式不清楚的话可以通过以下网址进行编辑:
http://blog.csdn.net/zadarrien_china/article/details/53422753
这个网址是对MediaType的讲解
第二种方式:第二种方式为一对一的形式主要为map类型。一般我们在开发工程中传照片的时候都是一个键值传递多张照片。但是有的时候会出现键值一对一的形式。这个时候不能再用list那种形式传递数据了。因此可以使用map的形式。例子如下
/** * 将文件进行转换 * @param param 为文件类型 * @return */ public static RequestBody convertToRequestBodyMap(File param){ RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), param); return requestBody; }
BaseBean就是你封装的Bean类返回的参数需要根据你的返回参数来进行编写
/** * code : USR000 * msg : SUCCESS * data :{} */
这个是我的返回格式,由于我的data里面没有数据所以泛型我就没有添加。如果你的data里面有数据的话需要将你的生成的类作为泛型进行添加。可以看我上一篇BaseBean类的编写。如果不清楚可以问我。共同学习。 @Url为你传递的自路径。有人会问你为啥不用@Path呢?由于path不能使用“/”进来路径的拼接。 @PartMap就是为你传递图片的注解可以将参数传递过去。但是值必须是RequestBody上面的工具类已经有对file转换为requestBody的封装。有人要问了我传递图片文件的时候同时需要传递参数咋办,同样将参数封装为RequestBody,添加到map中然后上传。下面是我的传递图片和参数的例子:如果有问题可以联系我。
public Map<String, RequestBody> getParams() { Map<String, RequestBody> map = new HashMap<>(); map.put("sessionid", convertToRequestBody("9e68dc89b0974e75aca2f15a8c6371b0")); map.put("postTitle", convertToRequestBody("123")); map.put("postText", convertToRequestBody("321")); map.put("address", convertToRequestBody("123")); map.put("topicId", convertToRequestBody("6")); File file = new File("/storage/emulated/0/Tencent/MicroMsg/oauth_qrcode.png"); // key + "\"; filename=\"" + ((File) o).getName() //todo 这个地方出现的bug,就是没有将key和后面的文件名进行拼接导致传递过程中不知道类型导致为空 //todo 拼接方式 key+"\"; filename=\"" + 文件名就可以了 map.put("list"+ "\"; filename=\"" + file.getName(), RequestBodyUtil .convertToRequestBodyMap(file)); return map; }
这个地方说一个小的bug就是自己大意造成的。就是咋传递文件的时候需要进行一个拼接,拼接个数如: //todo 拼接方式 key+"\"; filename=\"" + 文件名就可以了,由于参数和文件一起上传,无法区分文件还是参数。所以要添加区分。大概就这些。如果各位大神有更好的上传方式希望能够分享。
下面为一个大神的上传下载进度库: https://github.com/JessYanCoding/ProgressManager/blob/master/README-zh.md
如果涉及到侵权。请及时通知立刻删除