Retrofit 上传多文件方式:
一 .Multipart & MultipartBody.Part:
Api Service:
//上传多个文件.单文件就把List去掉
@Multipart
@POST(WX_URL)
Call<ResponseBody> uploadGatherInfo(@PartMap Map<String, RequestBody> params,
@Part List<MultipartBody.Part> files);
params :额外的属性参数
files:文件参数
注解PartMap对应的Map(这里指params)的value有2种方式处理
1.如果value的类型是okhttp3.RequestBody RequestBody,该值将与它的内容类型直接使用。
2.其他对象类型将通过使用 Converter 转换为适当的表示形式。
Send Request:
Map<String, RequestBody> bodyMap = RetrofitTransUtil.map2RequestBody(transParams);
List<MultipartBody.Part> multipart = RetrofitTransUtil.map2Multipart(fileParams);
if (multipart == null) {
Log.d("Trans File","文件不存在");
return;
}
//同步
Response<ResponseBody> response = RequestService.getWxService().
uploadGatherInfo(bodyMap, multipart).execute();
//异步
RequestService.getWxService().
uploadGatherInfo(bodyMap, multipart).enqueue(...);
因为封装传的额外参数是Map<String, Object> transParams ,要把transParams转换成Map<String,RequestBody>
传的File参数是Map<String,String> fileParams ,要把fileParams转换成 List<MultipartBody.Part>
public class RetrofitTransUtil {
public static MultipartBody.Part file2Part(File file){
return file2Part("file",file);
}
public static MultipartBody.Part file2Part(String name,File file){
RequestBody bodySingle = RequestBody.create(MultipartBody.FORM,file);
final MultipartBody.Part bodyPart = MultipartBody.Part.createFormData(
name, file.getName(),bodySingle);
return bodyPart;
}
public static RequestBody string2RequestBody(String param){
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), param);
return requestBody;
}
public static Map<String,RequestBody> map2RequestBody(Map<String,Object> params){
Map<String,RequestBody> map = new HashMap<String, RequestBody>();
if (params!= null && !params.isEmpty()) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
if (entry.getValue() != null) {
if (entry.getValue() instanceof String) {
map.put(entry.getKey(), RetrofitTransUtil.
string2RequestBody(String.valueOf(entry.getValue())));
}
/*if (entry.getValue() instanceof File) {
File f = (File) entry.getValue();
builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
} else {
builder.addFormDataPart(entry.getKey(), entry.getValue().toString());
}*/
}
}
}
return map;
}
public static List<MultipartBody.Part> map2Multipart(Map<String,String> params) {
List<MultipartBody.Part> parts = new ArrayList<>();
if (params != null && !params.isEmpty()) {
for (Map.Entry<String, String> entry : params.entrySet()) {
if (entry.getValue() != null && entry.getValue().length() != 0) {
File file = new File(entry.getValue());
if (file.exists()) {
parts.add(file2Part(entry.getKey(), file));
}else{
return null;
}
/*if (entry.getValue() instanceof File) {
File f = (File) entry.getValue();
builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
} else {
builder.addFormDataPart(entry.getKey(), entry.getValue().toString());
}*/
}
}
}
return parts;
}
二 .Multipart & RequestBody:
//上传文件
@Multipart
@POST("upload")
Call<String> uploadFile(@Part("file") RequestBody file);
注解Part对应参数类型以下三种方式之一处理:
1.如果类型是MultipartBody.Part,内容将直接使用。从注解中省略名称(例如,@Part MultipartBody.Part part})。2.如果类型是okhttp3.RequestBody RequestBody,该值将与它的内容类型直接使用。在注解中提供part名称(例如,@Part(“foo”) RequestBody foo)
3.其他对象类型将通过使用 Converter转换为合适的表示形式。在注解中提供Part名称(例如,* {@code @Part(“foo”) Image photo})
RequestBody bodySingle = RequestBody.create(MultipartBody.FORM,file);
RequestBody body = RequestBody.create(MediaType.parse(“image/jpeg”),file)
当然你也可以用@PartMap Map<String,RequestBody> map 来上传多个文件,不过要拼接Form参数 “file”; filename=""+ your file name 作为key, RequestBody作为value
参考:https://blog.youkuaiyun.com/Cricket_7/article/details/89668235
https://www.jianshu.com/p/74b7da380855
三:Body
@POST("/upload.php")
public Call<String> upload(@Body RequestBody file);
这种方式函数不可以使用@Multipart注解和@FormUrlEncoded注解,并且@Body注解只能使用一次,函数的参数类型没有要求,只要可以通过Convert转换成RequestBody就行,不过上传文件一般用直接用RequestBody。如果使用MultipartBody类型作为参数,一定要设置type为MultipartBody.FORM
参考:https://www.jianshu.com/p/e1012490c886
https://www.jianshu.com/p/acfefb0a204f
这种方法,我没有用过O(∩_∩)O