亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Retrofit2.0 公共參數(shù)(固定參數(shù))

 更新時(shí)間:2018年04月02日 10:42:33   作者:一葉飄舟  
這篇文章主要介紹了Retrofit2.0 公共參數(shù)(固定參數(shù)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

本文主要介紹了Retrofit2.0 公共參數(shù)(固定參數(shù)),分享給大家,具體如下:

請(qǐng)先閱讀:
Retrofit 動(dòng)態(tài)參數(shù)(非固定參數(shù)、非必須參數(shù))(Get、Post請(qǐng)求)

在實(shí)際項(xiàng)目中,對(duì)于有需要統(tǒng)一進(jìn)行公共參數(shù)添加的網(wǎng)絡(luò)請(qǐng)求,可以使用下面的代碼來(lái)實(shí)現(xiàn):

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint(ctx).setRequestInterceptor(new RequestInterceptor() {
     @Override
     public void intercept(RequestFacade request) {
      request.addQueryParam("publicParams", "1");
     }
    }).setConverter(new BaseConverter())
    .build();

在RestAdapter的實(shí)例化對(duì)象的時(shí)候,為其指定一個(gè)RequestInterceptor接口的實(shí)現(xiàn)類(lèi)即可,在該類(lèi)中,可以對(duì)請(qǐng)求體的相關(guān)參數(shù)進(jìn)行設(shè)置,如addHeader、addQueryParam等。

不過(guò)遺憾的是Retrofit2.0已經(jīng)沒(méi)有了該類(lèi),該怎么做呢?通過(guò)Interceptor實(shí)現(xiàn)。

Interceptor是攔截器, 在發(fā)送之前, 添加一些參數(shù), 或者獲取一些信息。

/**
 * 封裝公共參數(shù)(Key和密碼)
 * <p>
 */
public class CommonInterceptor implements Interceptor {
 private final String mApiKey;
 private final String mApiSecret;

 public CommonInterceptor(String apiKey, String apiSecret) {
  mApiKey = apiKey;
  mApiSecret = apiSecret;
 }

 @Override public Response intercept(Interceptor.Chain chain) throws IOException {
  String marvelHash = ApiUtils.generateMarvelHash(mApiKey, mApiSecret);
  Request oldRequest = chain.request();

  // 添加新的參數(shù)
  HttpUrl.Builder authorizedUrlBuilder = oldRequest.url()
    .newBuilder()
    .scheme(oldRequest.url().scheme())
    .host(oldRequest.url().host())
    .addQueryParameter(MarvelService.PARAM_API_KEY, mApiKey)
    .addQueryParameter(MarvelService.PARAM_TIMESTAMP, ApiUtils.getUnixTimeStamp())
    .addQueryParameter(MarvelService.PARAM_HASH, marvelHash);

  // 新的請(qǐng)求
  Request newRequest = oldRequest.newBuilder()
    .method(oldRequest.method(), oldRequest.body())
    .url(authorizedUrlBuilder.build())
    .build();

  return chain.proceed(newRequest);
 }
}

Okhttp3使用了裝飾者模式, 使用Builder添加Interceptor。

CommonInterceptor commonInterceptor = new CommonInterceptor(
    "key", "Secret");

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(commonInterceptor)
    .build();

// 適配器
Retrofit retrofit = new Retrofit.Builder()
  .baseUrl("url")    
  .addConverterFactory(GsonConverterFactory.create()
  .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
  .client(client)
  .build();

有時(shí)候你找到了一條線,就能順著線找到更多。

背景

在 Android Http API 請(qǐng)求開(kāi)發(fā)中經(jīng)常遇到這樣的需求:每一次請(qǐng)求帶上一個(gè)或者多個(gè)固定不變的參數(shù),例如:

  1. 設(shè)備唯一標(biāo)識(shí):device_id = 7a4391e28f309c21
  2. 業(yè)務(wù)唯一標(biāo)識(shí):uid = 2231001
  3. 平臺(tái)類(lèi)型:platform = android
  4. 客戶端版本號(hào):version_code = 6

這些參數(shù)是每一次發(fā)生請(qǐng)求都需要的,我們姑且稱他們?yōu)楣矃?shù)(或者基礎(chǔ)參數(shù))。公共參數(shù)一般以 header line、url query 或者 post body(較少) 這些形式插入請(qǐng)求。

實(shí)現(xiàn)

如果使用 OkHttp 作為 http request client, 這件事情就變得簡(jiǎn)單多了。OkHttp 提供了強(qiáng)大的攔截器組件 (Interceptor):

Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls.

也就是說(shuō),OkHttp 的攔截器功能之一就是對(duì)將要發(fā)出的請(qǐng)求進(jìn)行攔截、改造然后再發(fā)出。這正是我們想要的。BasicParamsInterceptor 實(shí)現(xiàn)了 okhttp3.Interceptor 接口。

實(shí)現(xiàn) public Response intercept(Chain chain) throws IOException 方法。使用 Builder 模式,暴露以下接口:

addParam(String key, String value)

post 請(qǐng)求,且 body type 為 x-www-form-urlencoded 時(shí),鍵值對(duì)公共參數(shù)插入到 body 參數(shù)中,其他情況插入到 url query 參數(shù)中。

addParamsMap(Map paramsMap)

同上,不過(guò)這里用鍵值對(duì) Map 作為參數(shù)批量插入。

addHeaderParam(String key, String value)

在 header 中插入鍵值對(duì)參數(shù)。

addHeaderParamsMap(Map headerParamsMap)

在 header 中插入鍵值對(duì) Map 集合,批量插入。

addHeaderLine(String headerLine)

在 header 中插入 headerLine 字符串,字符串需要符合 -1 != headerLine.indexOf(“:”) 的規(guī)則,即可以解析成鍵值對(duì)。

addHeaderLinesList(List headerLinesList)

同上,headerLineList: List 為參數(shù),批量插入 headerLine。

addQueryParam(String key, String value)

插入鍵值對(duì)參數(shù)到 url query 中。

addQueryParamsMap(Map queryParamsMap)

插入鍵值對(duì)參數(shù) map 到 url query 中,批量插入。

示例

使用 Buider 模式創(chuàng)建 Interceptor 對(duì)象,然后調(diào)用 OkHttp 的 addInterceptor(Interceptor i) 方法將 interceptor 對(duì)象添加至 client 中:

BasicParamsInterceptor basicParamsInterceptor =
  new OkPublicParamsInterceptor.Builder()
    .addHeaderParam("device_id", DeviceUtils.getDeviceId())
    .addParam("uid", UserModel.getInstance().getUid())
    .addQueryParam("api_version", "1.1")
    .build();
OkHttpClient client = new OkHttpClient.Builder()
  .addInterceptor(basicParamsInterceptor)
  .build();

TODO

  1. 自動(dòng)時(shí)間戳公共參數(shù)的支持
  2. 動(dòng)態(tài)參數(shù)的支持(例如登錄后插入服務(wù)器返回的 uid)

源碼

源碼與引用:https://github.com/jkyeo/okhttp-basicparamsinterceptor

basicparamsinterceptor應(yīng)用

配置基本提交參數(shù)

我們可以建一個(gè)攔截器,這里我舉例加些簡(jiǎn)單的系統(tǒng)參數(shù),如下:

 class HttpBaseParamsLoggingInterceptor implements Interceptor{

  @Override
  public Response intercept(Chain chain) throws IOException {
   Request request = chain.request();
   Request.Builder requestBuilder = request.newBuilder();
   RequestBody formBody = new FormBody.Builder()
   .add("userId", "10000")
   .add("sessionToken", "E34343RDFDRGRT43RFERGFRE")
   .add("q_version", "1.1")
   .add("device_id", "android-344365")
   .add("device_os", "android")
   .add("device_osversion","6.0")
   .add("req_timestamp", System.currentTimeMillis() + "")
   .add("app_name","forums")
   .add("sign", "md5")
   .build();
   String postBodyString = Utils.bodyToString(request.body());
   postBodyString += ((postBodyString.length() > 0) ? "&" : "") + Utils.bodyToString(formBody);
   request = requestBuilder
     .post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"),
       postBodyString))
     .build();
   return chain.proceed(request);
  }
 }

上面Utils類(lèi)是使用的okio.Buffer里面的工具類(lèi)。通過(guò)RequestBody構(gòu)建要上傳的一些基本公共的參數(shù),然后通過(guò)”&”符號(hào)在http 的body里面其他要提交參數(shù)拼接。然后再通過(guò)requestBuilder重新創(chuàng)建request對(duì)象,然后再通過(guò)chain.proceed(request)返回Response 。

接下來(lái)在創(chuàng)建OkHttpClient對(duì)象的時(shí)候修改為如下代碼:

mOkHttpClient = new OkHttpClient.Builder()
  .addInterceptor(interceptor)
  .addInterceptor(new HttpBaseParamsLoggingInterceptor())
  .build();

這樣就添加好了一些基本的公共參數(shù)。

下面我們借助BasicParamsInterceptor實(shí)現(xiàn),代碼如下:

public class BasicParamsInterceptor implements Interceptor {

 Map<String, String> queryParamsMap = new HashMap<>();
 Map<String, String> paramsMap = new HashMap<>();
 Map<String, String> headerParamsMap = new HashMap<>();
 List<String> headerLinesList = new ArrayList<>();

 private BasicParamsInterceptor() {

 }

 @Override
 public Response intercept(Chain chain) throws IOException {

  Request request = chain.request();
  Request.Builder requestBuilder = request.newBuilder();

  // process header params inject
  Headers.Builder headerBuilder = request.headers().newBuilder();
  if (headerParamsMap.size() > 0) {
   Iterator iterator = headerParamsMap.entrySet().iterator();
   while (iterator.hasNext()) {
    Map.Entry entry = (Map.Entry) iterator.next();
    headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
   }
  }

  if (headerLinesList.size() > 0) {
   for (String line: headerLinesList) {
    headerBuilder.add(line);
   }
  }

  requestBuilder.headers(headerBuilder.build());
  // process header params end




  // process queryParams inject whatever it's GET or POST
  if (queryParamsMap.size() > 0) {
   injectParamsIntoUrl(request, requestBuilder, queryParamsMap);
  }
  // process header params end




  // process post body inject
  if (request.method().equals("POST") && request.body().contentType().subtype().equals("x-www-form-urlencoded")) {
   FormBody.Builder formBodyBuilder = new FormBody.Builder();
   if (paramsMap.size() > 0) {
    Iterator iterator = paramsMap.entrySet().iterator();
    while (iterator.hasNext()) {
     Map.Entry entry = (Map.Entry) iterator.next();
     formBodyBuilder.add((String) entry.getKey(), (String) entry.getValue());
    }
   }
   RequestBody formBody = formBodyBuilder.build();
   String postBodyString = bodyToString(request.body());
   postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);
   requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
  } else { // can't inject into body, then inject into url
   injectParamsIntoUrl(request, requestBuilder, paramsMap);
  }

  request = requestBuilder.build();
  return chain.proceed(request);
 }

 // func to inject params into url
 private void injectParamsIntoUrl(Request request, Request.Builder requestBuilder, Map<String, String> paramsMap) {
  HttpUrl.Builder httpUrlBuilder = request.url().newBuilder();
  if (paramsMap.size() > 0) {
   Iterator iterator = paramsMap.entrySet().iterator();
   while (iterator.hasNext()) {
    Map.Entry entry = (Map.Entry) iterator.next();
    httpUrlBuilder.addQueryParameter((String) entry.getKey(), (String) entry.getValue());
   }
  }

  requestBuilder.url(httpUrlBuilder.build());
 }

 private static String bodyToString(final RequestBody request){
  try {
   final RequestBody copy = request;
   final Buffer buffer = new Buffer();
   if(copy != null)
    copy.writeTo(buffer);
   else
    return "";
   return buffer.readUtf8();
  }
  catch (final IOException e) {
   return "did not work";
  }
 }

 public static class Builder {

  BasicParamsInterceptor interceptor;

  public Builder() {
   interceptor = new BasicParamsInterceptor();
  }

  public Builder addParam(String key, String value) {
   interceptor.paramsMap.put(key, value);
   return this;
  }

  public Builder addParamsMap(Map<String, String> paramsMap) {
   interceptor.paramsMap.putAll(paramsMap);
   return this;
  }

  public Builder addHeaderParam(String key, String value) {
   interceptor.headerParamsMap.put(key, value);
   return this;
  }

  public Builder addHeaderParamsMap(Map<String, String> headerParamsMap) {
   interceptor.headerParamsMap.putAll(headerParamsMap);
   return this;
  }

  public Builder addHeaderLine(String headerLine) {
   int index = headerLine.indexOf(":");
   if (index == -1) {
    throw new IllegalArgumentException("Unexpected header: " + headerLine);
   }
   interceptor.headerLinesList.add(headerLine);
   return this;
  }

  public Builder addHeaderLinesList(List<String> headerLinesList) {
   for (String headerLine: headerLinesList) {
    int index = headerLine.indexOf(":");
    if (index == -1) {
     throw new IllegalArgumentException("Unexpected header: " + headerLine);
    }
    interceptor.headerLinesList.add(headerLine);
   }
   return this;
  }

  public Builder addQueryParam(String key, String value) {
   interceptor.queryParamsMap.put(key, value);
   return this;
  }

  public Builder addQueryParamsMap(Map<String, String> queryParamsMap) {
   interceptor.queryParamsMap.putAll(queryParamsMap);
   return this;
  }

  public BasicParamsInterceptor build() {
   return interceptor;
  }

 }
}

只要像上面一樣配置就行了。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Flutter 使用cached_image_network優(yōu)化圖片加載體驗(yàn)

    Flutter 使用cached_image_network優(yōu)化圖片加載體驗(yàn)

    在 Flutter 中,cached_image_network 即提供了緩存網(wǎng)絡(luò)圖片功能,同時(shí)還提供了豐富的加載過(guò)程指示。本文就來(lái)看下cached_image_network的具體使用
    2021-05-05
  • android實(shí)現(xiàn)icon動(dòng)態(tài)旋轉(zhuǎn)效果

    android實(shí)現(xiàn)icon動(dòng)態(tài)旋轉(zhuǎn)效果

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)icon動(dòng)態(tài)旋轉(zhuǎn)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • RecyclerView優(yōu)雅實(shí)現(xiàn)復(fù)雜列表布局

    RecyclerView優(yōu)雅實(shí)現(xiàn)復(fù)雜列表布局

    這篇文章主要為大家詳細(xì)介紹了RecyclerView優(yōu)雅實(shí)現(xiàn)復(fù)雜列表布局,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Android?Drawable代碼編寫(xiě)的新姿勢(shì)分享

    Android?Drawable代碼編寫(xiě)的新姿勢(shì)分享

    Drawable是什么?按照字面翻譯,就是可繪制的,由于能夠繪制的東西很多,所以這個(gè)類(lèi)是一個(gè)抽象類(lèi),下面這篇文章主要給大家介紹了關(guān)于Android?Drawable代碼編寫(xiě)的新姿勢(shì),需要的朋友可以參考下
    2022-01-01
  • android之listview懸浮topBar效果

    android之listview懸浮topBar效果

    這篇文章主要為大家詳細(xì)介紹了android之listview懸浮topBar效果的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Android 簡(jiǎn)單跳轉(zhuǎn)頁(yè)面工具的實(shí)例詳解

    Android 簡(jiǎn)單跳轉(zhuǎn)頁(yè)面工具的實(shí)例詳解

    這篇文章主要介紹了Android 簡(jiǎn)單跳轉(zhuǎn)頁(yè)面工具的實(shí)例詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 詳解Android 檢測(cè)權(quán)限的三種寫(xiě)法

    詳解Android 檢測(cè)權(quán)限的三種寫(xiě)法

    這篇文章主要介紹了詳解Android 檢測(cè)權(quán)限的三種寫(xiě)法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • Android封裝對(duì)原生Log進(jìn)行封裝的操作

    Android封裝對(duì)原生Log進(jìn)行封裝的操作

    這篇文章主要介紹了Android封裝對(duì)原生Log進(jìn)行封裝的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Android DataBinding單向數(shù)據(jù)綁定深入探究

    Android DataBinding單向數(shù)據(jù)綁定深入探究

    看了谷歌官方文章確實(shí)寫(xiě)的太簡(jiǎn)略了,甚至看完之后有很多地方還不知道怎么回事兒或者怎么用,那么接下來(lái)我將通過(guò)文章全面介紹一下DataBinding單向數(shù)據(jù)綁定
    2022-11-11
  • Android應(yīng)用開(kāi)發(fā)中單元測(cè)試分析

    Android應(yīng)用開(kāi)發(fā)中單元測(cè)試分析

    這篇文章主要介紹了Android應(yīng)用開(kāi)發(fā)中單元測(cè)試的作用,以及何為單元測(cè)試,深入學(xué)習(xí)Android應(yīng)用開(kāi)發(fā)中單元測(cè)試,需要的朋友可以參考下
    2015-12-12

最新評(píng)論