這篇文章主要為大家展示了“如何為Retrofit統(tǒng)一添加post請求的默認(rèn)參數(shù)”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“如何為Retrofit統(tǒng)一添加post請求的默認(rèn)參數(shù)”這篇文章吧。
在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"),
實(shí)際項目中通常最后的請求參數(shù)都包含默認(rèn)的一些參數(shù)(Token,Api版本、App版本等)和普通的請求參數(shù)。網(wǎng)上有很多關(guān)于第一種 Content-Type 添加默認(rèn)參數(shù)的方法。而在我現(xiàn)有項目上,除文件上傳外絕大多數(shù)請求都走了 post + application/json 的方式。這里暫不討論兩者的優(yōu)缺點(diǎn),而是談下 Content-Type 為 application/json 時,如何添加默認(rèn)參數(shù)。
傳統(tǒng)方式:
我們先來回憶下兩種方式
public interface Apis { @POST("user/login") Observable<Entity<User>> login(@Body RequestBody body);//構(gòu)造一個RequestBody對象 @POST("user/login") Observable<Entity<User>> login(@Body LoginInfo loginInfo);//構(gòu)造一個實(shí)體對象 }
第二種方法,你需要為每一個請求的對象創(chuàng)建一個不同的Model,太麻煩了,這里選擇第一種直接構(gòu)造RequestBody對象:
Retrofit mRetrofit = new Retrofit.Builder() .baseUrl(HttpConfig.BASE_URL) .addConverterFactory(GsonConverterFactory.create())//添加gson轉(zhuǎn)換器 .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加rxjava轉(zhuǎn)換器 .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í)行后通過抓包查看,請求體如下:
而我希望的結(jié)果是這樣的:
當(dāng)然我們可以每次構(gòu)造 RequestBody,在傳入的參數(shù)中加入默認(rèn)參數(shù):
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的同學(xué)已經(jīng)想到這種方式了,是的很多網(wǎng)上關(guān)于第一種 Content-Type 添加默認(rèn)參數(shù)也是這么做的(原文鏈接):
@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(); //把原來的參數(shù)添加到新的構(gòu)造器,(因?yàn)闆]找到直接添加,所以就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類型,如果是的話,將里面的鍵值對取出,并添加默認(rèn)參數(shù)的鍵值對并構(gòu)造出一個新的formBody對象,最后將原來用request對象構(gòu)造出新的一個request對象,將新的formBody對象穿進(jìn)去,攔截器返回。formBody對象是 Content-Type 為 application/x-www-form-urlencoded 時,Retrofit為我們生成的對象,它是RequestBody的子類;而 Content-Type 為 application/json 時,生成的就是 RequestBody (準(zhǔn)確的說是匿名子類)。所以我們只要繼承重寫 RequestBody ,記錄請求內(nèi)容,再將它在攔截器里取出加入并處理就行了。
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數(shù)據(jù),并添加新的默認(rèn)參數(shù):
@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()); }
這樣在外面我們只要改動一行代碼就可以實(shí)現(xiàn)全局添加默認(rèn)參數(shù):
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請求的默認(rèn)參數(shù)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站名稱:如何為Retrofit統(tǒng)一添加post請求的默認(rèn)參數(shù)-創(chuàng)新互聯(lián)
網(wǎng)址分享:http://chinadenli.net/article10/dgdgdo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、營銷型網(wǎng)站建設(shè)、標(biāo)簽優(yōu)化、網(wǎng)頁設(shè)計公司、云服務(wù)器、移動網(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)