成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Retrofit2.0怎么實(shí)現(xiàn)圖文上傳

這篇文章將為大家詳細(xì)講解有關(guān)Retrofit2.0怎么實(shí)現(xiàn)圖文上傳,小編覺得挺實(shí)用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)建站主要企業(yè)基礎(chǔ)官網(wǎng)建設(shè),電商平臺建設(shè),移動手機(jī)平臺,小程序開發(fā)等一系列專為中小企業(yè)按需制作網(wǎng)站產(chǎn)品體系;應(yīng)對中小企業(yè)在互聯(lián)網(wǎng)運(yùn)營的各種問題,為中小企業(yè)在互聯(lián)網(wǎng)的運(yùn)營中保駕護(hù)航。

最近項(xiàng)目里用到了類似圖文上傳的功能,以前都是封裝OkHttp的文件上傳功能,這次想換個姿勢,想用Retrofit2.0實(shí)現(xiàn)這樣的功能,本來以為挺簡單的,沒想到進(jìn)入了深坑,連續(xù)調(diào)整了好幾種姿勢都報(bào)了同一個錯,接著網(wǎng)上類似的文章找了一大推,講得都是模棱兩可,或者對多參數(shù)格式不夠友好,最后還是去看了相關(guān)的源碼,自己把這個問題提出來解決了,在這里記錄一下。

一、定義網(wǎng)絡(luò)請求接口

public interface GoodsReturnApiService {
  @Multipart
  @POST(Compares.GOODS_RETURN_POST)  //這里是自己post文件的地址
  Observable<GoodsReturnPostEntity> postGoodsReturnPostEntitys(@PartMap Map<String, RequestBody> map, @Part List<MultipartBody.Part> parts);
}

上面定義了一個接口用于上傳文件請求,有幾個注解需要說明一下, @Multipart這是Retrofit專門用于文件上傳的注解,需要配合@POST一起使用。

方法postGoodsReturnPostEntitys(@PartMap Map<String, RequestBody> map, @Part List<MultipartBody.Part> parts)第一個參數(shù)使用注解@PartMap用于多參數(shù)的情況,如果是單個參數(shù)也可使用注解@Part。

在類型Map<String, RequestBody>中,Map第一個泛型String是服務(wù)器接收用于文件上傳參數(shù)字段的Key,第二個泛型RequestBody是OkHttp3包裝的上傳參數(shù)字段的Value,這也是圖文上傳成功的關(guān)鍵所在。在后面會具體說到。

第二個參數(shù)使用注解@Part用于文件上傳,多文件上傳使用集合類型List<MultipartBody.Part>,單文件可以使用類型MultipartBody.Part,具體的使用同樣后面講。

這里著重說明一下,postGoodsReturnPostEntitys(@PartMap Map<String, RequestBody> map, @Part List<MultipartBody.Part> parts)方法參數(shù)這樣寫純屬個人習(xí)慣,你也可以直接使用一個參數(shù)postGoodsReturnPostEntitys(@PartMap Map<String, RequestBody> map),不過后面對RequestBody的處理方式也要跟著變化,這里就不詳細(xì)說了,只會介紹上面這種簡便清晰的方式。

二、初始化Retrofit

public class HttpRequestClient {

  public static final String TAG = "HttpRequestClientTAG";

  private static Retrofit retrofit;

  private static OkHttpClient getOkHttpClient() {
    //日志顯示級別
    HttpLoggingInterceptor.Level level= HttpLoggingInterceptor.Level.BODY;
    //新建log攔截器
    HttpLoggingInterceptor loggingInterceptor=new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
      @Override
      public void log(String message) {
        Log.d(TAG, message);
      }
    });
    loggingInterceptor.setLevel(level);
    //定制OkHttp
    OkHttpClient.Builder httpClientBuilder = new OkHttpClient
        .Builder();
    //OkHttp進(jìn)行添加攔截器loggingInterceptor
    httpClientBuilder.addInterceptor(loggingInterceptor);
    return httpClientBuilder.build();
  }

  public static Retrofit getRetrofitHttpClient(){
    if(null == retrofit){
      synchronized (HttpRequestClient.class){
        if(null == retrofit){
          retrofit = new Retrofit.Builder()
              .client(getOkHttpClient())
              .baseUrl(Compares.URL)
              .addConverterFactory(GsonConverterFactory.create())
              .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
              .build();
        }
      }
    }
    return retrofit;
  }
}

為了演示,Retrofit封裝比較簡陋,為的是查看網(wǎng)絡(luò)攔截,就不詳細(xì)說了。

三、發(fā)起文件上傳請求

private void postGoodsPicToServer(){
    Map<String,RequestBody> params = new HashMap<>();
    //以下參數(shù)是偽代碼,參數(shù)需要換成自己服務(wù)器支持的
    params.put("type", convertToRequestBody("type"));
    params.put("title",convertToRequestBody("title"));
    params.put("info",convertToRequestBody("info");
    params.put("count",convertToRequestBody("count"));

    //為了構(gòu)建數(shù)據(jù),同樣是偽代碼
    String path2 = Environment.getExternalStorageDirectory() + File.separator + "test1.jpg";
    String path3 = Environment.getExternalStorageDirectory() + File.separator + "test1.jpg";

    List<File> fileList = new ArrayList<>();

    fileList.add(new File(path2));
    fileList.add(new File(path3));

    List<MultipartBody.Part> partList = filesToMultipartBodyParts(fileList);

    HttpRequestClient.getRetrofitHttpClient().create(GoodsReturnApiService.class)
        .postGoodsReturnPostEntitys(params,partList)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<GoodsReturnPostEntity>() {
          @Override
          public void onSubscribe(@NonNull Disposable d) {

          }

          @Override
          public void onNext(@NonNull GoodsReturnPostEntity goodsReturnPostEntity) {

          }

          @Override
          public void onError(@NonNull Throwable e) {

          }

          @Override
          public void onComplete() {

          }
        });
}

上面的params和fileList都是構(gòu)造的偽代碼,需要根據(jù)自己項(xiàng)目的業(yè)務(wù)需求改變。

下面是上傳文件成功第一個關(guān)鍵,對參數(shù)請求頭(姑且叫這個名字,對應(yīng)Retrofit上傳文件時參數(shù)那部分請求頭,下文件(圖片)請求頭同理,對應(yīng)文件那部分請求頭)的content-type賦值,使用convertToRequestBody()方法。

private RequestBody convertToRequestBody(String param){
    RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), param);
    return requestBody;
  }

因?yàn)镚sonConverterFactory.create()轉(zhuǎn)換器的緣故,會將參數(shù)請求頭的content-type值默認(rèn)賦值application/json,如果沒有進(jìn)行這步轉(zhuǎn)換操作,就可以在OKHttp3的日志攔截器中查看到這樣的賦值,這樣導(dǎo)致服務(wù)器不能正確識別參數(shù),導(dǎo)致上傳失敗,所以這里需要對參數(shù)請求頭的content-type設(shè)置一個正確的值:text/plain。

下面是上傳文件成功第二個關(guān)鍵的地方,將文件(圖片)請求頭的content-type使用方法filesToMultipartBodyParts()對其賦值"image/png",并返回MultipartBody.Part集合。

private List<MultipartBody.Part> filesToMultipartBodyParts(List<File> files) {
    List<MultipartBody.Part> parts = new ArrayList<>(files.size());
    for (File file : files) {
      RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);
      MultipartBody.Part part = MultipartBody.Part.createFormData("multipartFiles", file.getName(), requestBody);
      parts.add(part);
    }
    return parts;
  }

關(guān)于“Retrofit2.0怎么實(shí)現(xiàn)圖文上傳”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

當(dāng)前標(biāo)題:Retrofit2.0怎么實(shí)現(xiàn)圖文上傳
本文網(wǎng)址:http://jinyejixie.com/article10/jojcgo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、、小程序開發(fā)網(wǎng)站策劃、建站公司、營銷型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化
英山县| 江山市| 若尔盖县| 轮台县| 营山县| 康平县| 延吉市| 大姚县| 甘肃省| 南宫市| 甘肃省| 永州市| 金阳县| 柳州市| 德安县| 嘉定区| 平泉县| 阳江市| 南通市| 三江| 陇川县| 双峰县| 莒南县| 河北区| 绥宁县| 彩票| 忻城县| 香港| 崇明县| 大渡口区| 金寨县| 米林县| 酉阳| 绥滨县| 奉新县| 盐源县| 名山县| 六枝特区| 离岛区| 个旧市| 团风县|