国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

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

2019-10-22 18:13:19
字體:
來源:轉載
供稿:網友

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

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

在實際項目中,對于有需要統(tǒng)一進行公共參數(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的實例化對象的時候,為其指定一個RequestInterceptor接口的實現(xiàn)類即可,在該類中,可以對請求體的相關參數(shù)進行設置,如addHeader、addQueryParam等。

不過遺憾的是Retrofit2.0已經沒有了該類,該怎么做呢?通過Interceptor實現(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);  // 新的請求  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();

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

背景

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

  1. 設備唯一標識:device_id = 7a4391e28f309c21
  2. 業(yè)務唯一標識:uid = 2231001
  3. 平臺類型:platform = android
  4. 客戶端版本號:version_code = 6

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

實現(xiàn)

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

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

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

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

addParam(String key, String value)

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

addParamsMap(Map paramsMap)

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

addHeaderParam(String key, String value)

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

addHeaderParamsMap(Map headerParamsMap)

在 header 中插入鍵值對 Map 集合,批量插入。

addHeaderLine(String headerLine)

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

addHeaderLinesList(List headerLinesList)

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

addQueryParam(String key, String value)

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

addQueryParamsMap(Map queryParamsMap)

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

示例

使用 Buider 模式創(chuàng)建 Interceptor 對象,然后調用 OkHttp 的 addInterceptor(Interceptor i) 方法將 interceptor 對象添加至 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. 自動時間戳公共參數(shù)的支持
  2. 動態(tài)參數(shù)的支持(例如登錄后插入服務器返回的 uid)

源碼

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

basicparamsinterceptor應用

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

我們可以建一個攔截器,這里我舉例加些簡單的系統(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類是使用的okio.Buffer里面的工具類。通過RequestBody構建要上傳的一些基本公共的參數(shù),然后通過”&”符號在http 的body里面其他要提交參數(shù)拼接。然后再通過requestBuilder重新創(chuàng)建request對象,然后再通過chain.proceed(request)返回Response 。

接下來在創(chuàng)建OkHttpClient對象的時候修改為如下代碼:

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

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

下面我們借助BasicParamsInterceptor實現(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;  } }}

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 锡林郭勒盟| 鄂尔多斯市| 东丽区| 吉林省| 漳平市| 长丰县| 蓝田县| 安陆市| 青铜峡市| 新宾| 双峰县| 阜新市| 太和县| 宜丰县| 万荣县| 错那县| 涞源县| 扎鲁特旗| 彭山县| 长宁县| 沽源县| 息烽县| 开江县| 余姚市| 丹凤县| 崇明县| 江油市| 怀安县| 瑞安市| 富裕县| 蒙城县| 邓州市| 黎平县| 宜城市| 开远市| 江油市| 双牌县| 沙湾县| 东港市| 全椒县| 东莞市|