使用 retrofit2 上传文件的方法

Android

被坑了两天。。感觉这个必须得记下了。。。

使用 retrofit2 上传一张图到服务器,服务器上使用这样的 php 语句来获取文件

$file = $_FILES['image'];

ApiService 按照官方的文档使用Multipart就好,用不用 PartMap 就看喜好了

@Multipart
@POST("uploadImage.php")
Call<UploadInformationTransfer> uploadImage(@PartMap Map<String, RequestBody> params);

所有的参数都要用RequestBody包装一下

// 传入的纯文本 POST 参数,使用 $_POST['field'] 来获取
RequestBody apikey = RequestBody.create(MediaType.parse("text/plain"), ApiKeys.HARUUE_STORAGE_SERVER_2_APIKEY);
RequestBody use = RequestBody.create(MediaType.parse("text/plain"), "face");

// 传入的文件参数,使用 $_FILES['field'] 来获取
RequestBody imgFile = RequestBody.create(MediaType.parse("image/jpeg"), file);

然后把它们加入 PartMap ,如果不使用 PartMap ,把对应部分填到 @Part(“field”) 里去也可以

Map<String, RequestBody> partMap = new HashMap<>();
partMap.put("apikey", apikey);
partMap.put("use", use);
partMap.put("image\"; filename=\"upload.jpg\"", imgFile);

然后把这个 partMap 传入对应函数中,大功告成。。。

看起来很简单就像是 FormUrlEncoded 一样,然而,发现坑没有?

__注意:__在传入文件的时候,使用

partMap.put("image\"; filename=\"upload.jpg\"", imgFile);

实际上,上传的文件名与系统中存储的文件的真实文件名没有关系,只与这个字符串有关系。。。
所以,如果需要在服务器上使用$_FILES['参数名']来获取上传的文件,那么上传的时候就应该写

// 使用 PartMap
partMap.put("参数名\"; filename=\"文件名\"", imgFile);

// 直接在定义 ApiService 时使用 @Part 注释
Call<...> upload(..., @Part("参数名\"; filename=\"文件名\"") RequestBody file, ...);

因此,如果需要文件名可变,那么就必须使用 PartMap

partMap.put("参数名\"; filename=\"" + filename + "\"", imgFile);

Post Directory

文章目录