如何為Retrofit統(tǒng)一添加post請求的默認參數-創(chuàng)新互聯

這篇文章主要為大家展示了“如何為Retrofit統(tǒng)一添加post請求的默認參數”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“如何為Retrofit統(tǒng)一添加post請求的默認參數”這篇文章吧。

10年積累的網站設計、網站建設經驗,可以快速應對客戶對網站的新想法和需求。提供各種問題對應的解決方案。讓選擇我們的客戶得到更好、更有力的網絡服務。我雖然不認識你,你也不認識我。但先網站設計制作后付款的網站建設流程,更有南海免費網站建設讓你可以放心的選擇與我們合作。

在Http請求中我們使用 Content-Type 來指定不同格式的請求信息:

APP_FORM_URLENCODED("application/x-www-form-urlencoded"),
 APP_JSON("application/json"),
 APP_OCTET_STREAM("application/octet-stream"),
 MULTIPART_FORM_DATA("multipart/form-data"),
 TEXT_HTML("text/html"),
 TEXT_PLAIN("text/plain"),

實際項目中通常最后的請求參數都包含默認的一些參數(Token,Api版本、App版本等)和普通的請求參數。網上有很多關于第一種 Content-Type 添加默認參數的方法。而在我現有項目上,除文件上傳外絕大多數請求都走了 post + application/json 的方式。這里暫不討論兩者的優(yōu)缺點,而是談下 Content-Type 為 application/json 時,如何添加默認參數。

傳統(tǒng)方式:

我們先來回憶下兩種方式

public interface Apis {
 
 @POST("user/login")
 Observable<Entity<User>> login(@Body RequestBody body);//構造一個RequestBody對象
 
 @POST("user/login")
 Observable<Entity<User>> login(@Body LoginInfo loginInfo);//構造一個實體對象
 
 }

第二種方法,你需要為每一個請求的對象創(chuàng)建一個不同的Model,太麻煩了,這里選擇第一種直接構造RequestBody對象:

Retrofit mRetrofit = new Retrofit.Builder()
    .baseUrl(HttpConfig.BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())//添加gson轉換器
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加rxjava轉換器
    .client(new OkHttpClient.Builder().build())
    .build();
Apis mAPIFunction = mRetrofit.create(Apis.class);
Map<String, Object> params = new LinkedHashMap<>();
 params.put("name", "吳彥祖");
 params.put("request", "123456");
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JsonHelper.toJSONString(params));
mAPIFunction.login(RequestBody.create(requestBody))

執(zhí)行后通過抓包查看,請求體如下:

如何為Retrofit統(tǒng)一添加post請求的默認參數

而我希望的結果是這樣的:

如何為Retrofit統(tǒng)一添加post請求的默認參數

當然我們可以每次構造 RequestBody,在傳入的參數中加入默認參數:

public static RequestBody getRequestBody(HashMap<String, Object> hashMap) {
  Map<String, Object> params = new LinkedHashMap<>();
  params.put("auth", getBaseParams());
  params.put("request", hashMap);
  return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JsonHelper.toJSONString(params));
 }

這樣完全沒問題,但不夠優(yōu)雅,所以接下來我們來討論我所想到的一種方式

攔截器方式:

哈哈,相信熟悉OkHttp的同學已經想到這種方式了,是的很多網上關于第一種 Content-Type 添加默認參數也是這么做的(原文鏈接):

@Override
 public Response intercept(Chain chain) throws IOException {
  Request request = chain.request();
  if (request.method().equals("POST")) {
  if (request.body() instanceof FormBody) {
   FormBody.Builder bodyBuilder = new FormBody.Builder();
   FormBody formBody = (FormBody) request.body();
   //把原來的參數添加到新的構造器,(因為沒找到直接添加,所以就new新的)
   for (int i = 0; i < formBody.size(); i++) {
    bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
   }
   formBody = bodyBuilder
     .addEncoded("clienttype", "1")
     .addEncoded("imei", "imei")
     .addEncoded("version", "VersionName")
     .addEncoded("timestamp", String.valueOf(System.currentTimeMillis()))
     .build();

   request = request.newBuilder().post(formBody).build();
  }
   return chain.proceed(request);
  }

在上面,我們拿到了request對象,然后拿到了requestBody對象,然后 判斷是不是FormBody類型,如果是的話,將里面的鍵值對取出,并添加默認參數的鍵值對并構造出一個新的formBody對象,最后將原來用request對象構造出新的一個request對象,將新的formBody對象穿進去,攔截器返回。formBody對象是 Content-Type 為 application/x-www-form-urlencoded 時,Retrofit為我們生成的對象,它是RequestBody的子類;而 Content-Type 為 application/json 時,生成的就是 RequestBody (準確的說是匿名子類)。所以我們只要繼承重寫 RequestBody ,記錄請求內容,再將它在攔截器里取出加入并處理就行了。

public class PostJsonBody extends RequestBody {

 private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
 private static final Charset charset = Util.UTF_8;

 private String content;

 public PostJsonBody(@NonNull String content) {
  this.content = content;
 }

 public String getContent() {
  return content;
 }

 @Nullable
 @Override
 public MediaType contentType() {
  return JSON;
 }

 @Override
 public void writeTo(@NonNull BufferedSink sink) throws IOException {
  byte[] bytes = content.getBytes(charset);
  if (bytes == null) throw new NullPointerException("content == null");
  Util.checkOffsetAndCount(bytes.length, 0, bytes.length);
  sink.write(bytes, 0, bytes.length);
 }

 public static RequestBody create(@NonNull String content) {
  return new PostJsonBody(content);
 }
}

攔截器里面取出原始json數據,并添加新的默認參數:

@Override
 public Response intercept(@NonNull Chain chain) throws IOException {
  Request originalRequest = chain.request();
  Request.Builder builder = originalRequest.newBuilder();
  if (originalRequest.method().equals("POST")) {
   RequestBody requestBody = originalRequest.body();
   if (requestBody instanceof PostJsonBody) {
    String content = ((PostJsonBody) requestBody).getContent();
    HashMap<String, Object> hashMap = JsonHelper.fromJson(content, HashMap.class);
    builder.post(RequestBodyFactory.getRequestBody(hashMap));
   }
  }
  return chain.proceed(builder.build());
 }

這樣在外面我們只要改動一行代碼就可以實現全局添加默認參數:

RequestBody requestBody =
 RequestBody.create(MediaType.parse("application/json;charset=utf-8"),JsonHelper.toJSONString(params));

替換為:

RequestBody requestBody = PostJsonBody.create( JsonHelper.toJSONString(params));

以上是“如何為Retrofit統(tǒng)一添加post請求的默認參數”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注創(chuàng)新互聯行業(yè)資訊頻道!

網站名稱:如何為Retrofit統(tǒng)一添加post請求的默認參數-創(chuàng)新互聯
網址分享:http://bm7419.com/article10/dgdgdo.html

成都網站建設公司_創(chuàng)新互聯,為您提供軟件開發(fā)營銷型網站建設、標簽優(yōu)化、網頁設計公司、云服務器、移動網站建設

廣告

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

h5響應式網站建設