Retrofit學(xué)習(xí)之文件和參數(shù)上傳

個人主頁: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的注解环揽,否者會報錯

注意:

  1. 如果在上傳文件的時候,定義:
 @Multipart
@POST("upload")
Call<ResponseBody> uploadOneFile(@Part RequestBody file);

顯示下面的錯誤:

 @Part annotation must supply a name or use MultipartBody.Part parameter type. (parameter #1)
  1. 如果@Part加上參數(shù)庵佣,并RequestBody作為參數(shù)歉胶,上傳文件,服務(wù)端識別不出來這是一個文件巴粪,會當做一個參數(shù)上傳的例子
 @Multipart
@POST("upload")
Call<ResponseBody> uploadOneFile(@Part("file") RequestBody file);
  1. 如果使用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)注一下~肛根。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辫塌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子派哲,更是在濱河造成了極大的恐慌臼氨,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芭届,死亡現(xiàn)場離奇詭異储矩,居然都是意外死亡感耙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門持隧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來即硼,“玉大人,你說我怎么就攤上這事屡拨≈凰郑” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵洁仗,是天一觀的道長层皱。 經(jīng)常有香客問我,道長赠潦,這世上最難降的妖魔是什么叫胖? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮她奥,結(jié)果婚禮上瓮增,老公的妹妹穿的比我還像新娘。我一直安慰自己哩俭,他們只是感情好绷跑,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凡资,像睡著了一般砸捏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上隙赁,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天垦藏,我揣著相機與錄音,去河邊找鬼伞访。 笑死掂骏,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的厚掷。 我是一名探鬼主播弟灼,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼冒黑!你這毒婦竟也來了田绑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤抡爹,失蹤者是張志新(化名)和其女友劉穎辛馆,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡昙篙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年腊状,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苔可。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡缴挖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出焚辅,到底是詐尸還是另有隱情映屋,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布同蜻,位于F島的核電站棚点,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏湾蔓。R本人自食惡果不足惜瘫析,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望默责。 院中可真熱鬧贬循,春花似錦、人聲如沸桃序。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媒熊。三九已至奇适,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芦鳍,已是汗流浹背嚷往。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怜校,地道東北人间影。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓注竿,卻偏偏與公主長得像茄茁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子巩割,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容