個人主頁:http://shiyiliang.cn
今天主要來學(xué)習(xí)Retrofit的文件和參數(shù)的上傳鞋拟,如果你不是很了解上傳的原理骂维,你可以看下文件上傳原理,先了解下文件上傳的基本原理贺纲。
參數(shù)上傳
1. 參數(shù)個數(shù)不是很多時
@FormUrlEncoded
@POST("upload")
Call<ResponseBody> uploadParams(@Field("username")String username,@Field("token")String token);
使用直接傳入?yún)?shù)值即可
2. 多個參數(shù)上傳
@FormUrlEncoded
@POST("upload")
Call<ResponseBody> uploadParams(@FieldMap Map<String,String> map);
調(diào)用的時候航闺,直接傳入一個map集合,即可
3. 通用的方法
@POST("upload")
Call<ResponseBody> uploadParams(@Body RequestBody body);
調(diào)用時猴誊,傳入一個RequestBody
對象潦刃,OkHttp庫中有一個專門用來構(gòu)建參數(shù)上傳的RequestBody
子類,即FormBody
懈叹,如下
FormBody body=new FormBody.Builder()
.add("username","admin")
.add("token","sjdkdjows=dmzkkshf")
.build();
在使用的時候乖杠,直接調(diào)用uploadParams (body)
即可實現(xiàn)上傳。
文件上傳
1. 單個文件上傳
@Multipart
@POST("upload")
Call<ResponseBody> uploadOneFile(@Part MultipartBody.Part body);
調(diào)用的使用MultipartBody.Part
來構(gòu)造一個Part對象參數(shù)
String name = etFileName.getText().toString().trim();
name = TextUtils.isEmpty(name) ? "1.png" : name;
String path = Environment.getExternalStorageDirectory() + File.separator + name;
File file = new File(path);
RequestBody fileRQ = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part part MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);
Call<ResponseBody> uploadCall = downloadService.uploadOneFile(part);
2. 多文件上傳
使用@PartMap
實現(xiàn)
@Multipart
@POST("upload")
Call<ResponseBody> uploadFiles(@PartMap Map<String, RequestBody> map);
調(diào)用方法
RequestBody fb = RequestBody.create(MediaType.parse("text/plain"), "hello,retrofit");
RequestBody fileTwo = RequestBody.create(MediaType.parse("image/*"), new File(Environment.getExternalStorageDirectory()
+ file.separator + "original.png"));
Map<String, RequestBody> map = new HashMap<>();
//這里的key必須這么寫项阴,否則服務(wù)端無法識別
map.put("file\"; filename=\""+ file.getName(), fileRQ);
map.put("file\"; filename=\""+ "2.png", fileTwo);
Call<ResponseBody> uploadCall = downloadService.uploadFiles(map);
使用@Part
實現(xiàn)
@Multipart
@POST("upload")
Call<ResponseBody> uploadFiles(@Part List<MultipartBody.Part> parts);
調(diào)用代碼如下:
RequestBody fileRQ = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);
RequestBody fb = RequestBody.create(MediaType.parse("text/plain"), "hello,retrofit");
RequestBody fileTwo = RequestBody.create(MediaType.parse("image/*"), new File(Environment.getExternalStorageDirectory()
+ file.separator + "original.png"));
MultipartBody.Part two=MultipartBody.Part.createFormData("one","one.png",fileTwo);
List<MultipartBody.Part> parts=new ArrayList<>();
parts.add(part);
parts.add(two);
Call<ResponseBody> uploadCall = downloadService.uploadFiles(parts);
文件和參數(shù)混合上傳
@Multipart
@POST("upload")
Call<ResponseBody> uploadFile(@Part("body") RequestBody body, @Part MultipartBody.Part file);
MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);
RequestBody fb =RequestBody.create(MediaType.parse("text/plain"), "hello,retrofit");
Call<ResponseBody> uploadCall = downloadService.uploadFile(fb,part);
通用上傳方式
接口定義,注意這個時候沒有@Multipart
@POST("upload")
Call<ResponseBody> uploadFile(@Body RequestBody body);
利用MultipartBody
來實現(xiàn)通用的參數(shù)和文件上傳
String name = etFileName.getText().toString().trim();
name = TextUtils.isEmpty(name) ? "1.png" : name;
String path = Environment.getExternalStorageDirectory() + File.separator + name;
File file = new File(path);
RequestBody fileRQ = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData("picture", file.getName(), fileRQ);
RequestBody body=new MultipartBody.Builder()
.addFormDataPart("userName","lange")
.addFormDataPart("token","dxjdkdjkj9203kdckje0")
.addFormDataPart("header",file.getName(),fileRQ)
.build();
Call<ResponseBody> uploadCall = downloadService.uploadFile(body);
uploadCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.i("upload", response.isSuccessful() + "");
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
看下服務(wù)端的輸出:
userName-->lange
token-->dxjdkdjkj9203kdckje0
/Users/lange/Desktop/web/out/artifacts/web_war_exploded/upload/1.png
當我們采用這種方式上傳的時候笆包,不能再接口上加上
@Multipart
的注解环揽,否者會報錯
注意:
- 如果在上傳文件的時候,定義:
@Multipart
@POST("upload")
Call<ResponseBody> uploadOneFile(@Part RequestBody file);
顯示下面的錯誤:
@Part annotation must supply a name or use MultipartBody.Part parameter type. (parameter #1)
- 如果@Part加上參數(shù)庵佣,并RequestBody作為參數(shù)歉胶,上傳文件,服務(wù)端識別不出來這是一個文件巴粪,會當做一個參數(shù)上傳的例子
@Multipart
@POST("upload")
Call<ResponseBody> uploadOneFile(@Part("file") RequestBody file);
- 如果使用MultipartBody.Part作為參數(shù)通今,又加上了名字
uploadOneFile(@Part("file") MultipartBody.Part file)
則會顯示下面的錯誤
@Part parameters using the MultipartBody.Part must not include a part name in the annotation
如果你覺得文章讓你有一些收獲,你就贊賞下或者關(guān)注一下~肛根。