1. 程式人生 > >Rxjava+Retrofit實現多圖片上傳

Rxjava+Retrofit實現多圖片上傳

1、前言

專案需求:要求實現多張圖片上傳,並攜帶其他屬性值。
專案使用框架:Rxjava+Retrofit+Okhttp。
先附上大神寫的關於Retrofit的詳細用法,本文所寫以此文為基礎:Retrofit詳解

2、後臺介面

這裡寫圖片描述
這裡寫圖片描述
分析後臺介面,可以知道,我們需要以表單的形式上傳,並且需要上傳多張圖片。

3、前端定義介面

根據Retrofit註解知識可知,選用POST進行網路請求,請求體是一個Form表單,且需要支援多檔案上傳。
在Retrofit中表單請求分為兩種標記FromURLEncoded和Multipart兩類,前者與Field和FieldMap配合使用,後者與Part和PartMap配合使用;後者適合有檔案上傳的情況。
根據後臺提供的介面,前端最後定義的上傳介面如下:

    @Multipart
    @POST("visits/")
    Observable<Response<PostVisitsRespModel>> postVisitsInfo(@PartMap Map<String, RequestBody> files);

4、在程式碼中呼叫介面

拼裝PartMap:

                Map<String, RequestBody> images = new HashMap<String, RequestBody>();
                //一般引數
                images.put
("visit_type", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, visit_type)); images.put("demand", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, demand)); images.put("dept_id", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, depart_id)); images.put("visitor_id"
, RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, visitor_id+"")); images.put("expect_date", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, expect_time)); images.put("expert_name", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, expert)); images.put("hosp_id", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, hosp_id)); images.put("content", RequestBody.create(AppConstant.MEDIA_TYPE_TEXT, history)); //檔案(注意與上面的不同) if(imageFileList != null && !imageFileList.isEmpty()) { for (File file:imageFileList){ images.put("files\";filename=\""+file.getName(), RequestBody.create(AppConstant.MEDIA_TYPE_JPG, file)); } }

對上面的程式碼進行分析:
1、對於一般引數RequestBody只要指明引數型別即可。
2、對於多檔案上傳,不但要指明RequestBody的型別,還需要攜帶上“Content-Disposition請求頭”,請求頭中必須要有 filename=”xxx” 才會被當成檔案,所以我們在寫檔名的時候必須把 filename=”XXX” 也拼接上去,即檔名變成 “表單鍵名”; filename=”檔名“。此處是成功將檔案上傳的關鍵!

最後呼叫介面

mApiService.postVisitsInfo(images)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new BaseSubscriber<Response<PostVisitsRespModel>>(mContext, true, true) {

                            @Override
                            public void onNext(Response<PostVisitsRespModel> postVisitsRespModelResponse) {

                                setResult(RESULT_OK);
                                showToastMessage("訂單提交成功");

                                OrderActivity.this.finish();
                            }

                        });

5、有上面4個步驟就可以實現多檔案上傳了。不過,對於圖片上傳之前,最好對圖片進行壓縮,在專案中採用了Luban壓縮。

 Luban.with(mContext)
                            .load(mSelectPath)
                            //質量小於100kb後不再進行壓縮
                            .ignoreBy(100)
                             //壓縮後的檔案路徑                           
                            .setTargetDir(FileUtils.createMkdirs(AppConstant.P_IMAGE))
                            .setCompressListener(new OnCompressListener() {
                                @Override
                                public void onStart() {

                                }

                                @Override
                                public void onSuccess(File file) {
                                    //壓縮成功後的處理邏輯
                                }

                                @Override
                                public void onError(Throwable e) {
                                    Log.e("TAG", "Luban=" + e.getMessage());
                                }
                            }).launch();

6、結語:好了,多圖片上傳就介紹到這裡了。下面再附上一些實現多圖片上傳的博文