androidretrofit
『壹』 Android retrofit 註解@QueryMap和@Body的區別
如果你的項目是採用POST請求方式,不管是使用實體類還是使用HashMap最好採用@Body註解。雖然你使用QueryMap可能也不會有什麼問題(PS:這種共用的情況只適用於POST請求,GET請求不能使用@Body註解,否則會報錯)。
使用retrofit這樣框架快一年了,以前使用它傳遞參數時都是用@QueryMap註解傳遞,雖然知道這樣不是很好,但是當時換框架的時候看到工作量太大就沒有換成實體類形式了,之前的使用方式如下圖:
2.由於最近在研究java後台,搭建了一個SSM框架想測試一下;因為之前以為HashMap只能採用這種方式傳遞,在今天的測試中發現並不是,其實使用HashMap同樣可以採用@Body註解,而且@QueryMap跟@Body的區別非常大,先看按之前的方式使用@QueryMa
3.上面是android的代碼,使用了RxJava。在來看java後台的:
4.使用HttpServletRequest來接收是沒有問題的,但是如果後台使用@RequestBody來接收參數就沒法接收到了,而且連請求都沒接收到:
5.下面我們來看一下,androidStudio列印的日誌,發現後台返回了400,並且發現參數拼接到連接後面了,這不是GET的傳遞參數的方式嗎?但是我明明是POST註解請求:
6.我點擊註解看了下源碼,看到下面的注釋,第一句的大意就是說:會把key和value拼接到url後面,所以才會出現剛剛日誌中那種情況,而且看注釋都是在講GET請求下的使用,並沒有POST的使用介紹,所以我感覺這個註解是主要為GET請求准備的:
7.在來看@Body,先看源碼吧 ,注釋的大體意思是:使用這個註解可以把參數放到請求體中,適用於 POST/PUT請求:
8.然後再看使用方式,和@QueryMap 一樣的,而且它可以使用實體類,QueryMap 是不能註解實體類的:
9.在看列印的日誌:
10.從日誌看出來,這才是POST請求參數參數的方式。
總結一下:@QueryMap註解會把參數拼接到url後面,所以它適用於GET請求;@Body會把參數放到請求體中,所以適用於POST請求。
『貳』 Android上使用retrofit+okhttp時token失效的處理方案
提前聲明,以下提到的方案並沒有去驗證過可行性,只是記錄一下,未來需要用到的時候,在仔細驗證一下。
一般情況下,各個公司的移動端關於登錄令牌(token)的設定都各不相同。
可先參考這個鏈接: https://www.hu.com/question/30267006
了解一下,本文大概想說什麼。
有些公司服務端是按照oauth設計,比較標准規范,但是有些公司有自己的特定業務,未完全按照oauth來設計。基於本公司的業務邏輯,考慮了一下登錄的邏輯以及token的設計。
思路如下:
token即驗證令牌,每次請求都帶上,refreshToken用來刷新token的,每次請求可以不帶上,但是要放在移動端保存。
1.通過username,password獲取token和refreshToken
2.token的有效期為2小時,refreshToken的有效期為15天
3.如果伺服器端判斷token過期,而refreshToken未過期,就返回錯誤碼給客戶端,則客戶端通過一個特定的介面傳入refreshToken參數獲取新的token和refreshToken
4.如果連續15天未使用app或者用戶修改了密碼,則表示refreshToken過期了,則跳到登錄界面,重新登錄獲取token和refreshToken
基於上面的思路,如果服務端走rest風格,移動端(Android)採用retrofit(v2.0+)+okhttp(v2.7.0+)網路請求框架。那麼當token過期了,Android端應該如何處理呢?
通過okhttp提供的Authenticator介面,相關資料 點擊這里 ,但是查看okhttp的源碼會發現,只有返回HTTP的狀態碼為401時,才會使用Authenticator介面,如果服務端設計規范,可以嘗試如下方法。
實現Authenticator介面
然後給添加給OkHttpClient
第一種方案就這樣了。
但是,萬事不會盡如人意,如果服務端在token過期的時候,不給返回401的HTTP狀態碼,而是返回如下類型的數據,叫你根據code判斷。
這里要清楚HTTP狀態碼是指200,404,401這些,而上面的數據中的code是自定義的。如果在token過期時,服務端返回的是如上類型的數據,那麼第一種方案就行不通。
通過okhttp的攔截器,okhttp 2.2.0 以後提供了攔截器的功能,相關介紹 點擊這里
然後給okhttp設置攔截器
第二種方案的思路是通過攔截返回的數據,判斷token是否過期,如果過期則進行一次刷新token的操作。
上面2種方案都沒有進行實際驗證過,希望以後有機會能驗證。
完。。。
『叄』 【Android】Retrofit網路請求參數註解,@Path、@Query、@QueryMap...
對Retrofit已經使用了一點時間了,是時候歸納一下各種網路請求的service了。
下面分為GET、POST、DELETE還有PUT的請求,說明@Path、@Query、@QueryMap、@Body、@Field的用法。
http://102.10.10.132/api/News
http://102.10.10.132/api/News/1
http://102.10.10.132/api/News/ {資訊id}
或
http://102.10.10.132/api/News/1/ 類型1
http://102.10.10.132/api/News/ {資訊id}/{類型}
http://102.10.10.132/api/News?newsId=1
http://102.10.10.132/api/News?newsId= {資訊id}
或
http://102.10.10.132/api/News?newsId=1&type= 類型1
http://102.10.10.132/api/News?newsId= {資訊id}&type={類型}
http://102.10.10.132/api/News?newsId=1&type= 類型1...
http://102.10.10.132/api/News?newsId= {資訊id}&type={類型}...
也可以
http://102.10.10.132/api/Comments/1
http://102.10.10.132/api/Comments/ {newsId}
http://102.10.10.132/api/Comments/1?access_token=1234123
http://102.10.10.132/api/Comments/ {newsId}?access_token={access_token}
http://102.10.10.132/api/Comments/1?access_token=1234123
http://102.10.10.132/api/Comments/ {newsId}?access_token={access_token}
http://102.10.10.132/api/Comments/1
http://102.10.10.132/api/Comments/ {commentId}
http://102.10.10.132/api/Comments/1?access_token=1234123
http://102.10.10.132/api/Comments/ {commentId}?access_token={access_token}
http://102.10.10.132/api/Comments
CommentBody :需要提交的內容,與 Post 中的 Body 相同
http://102.10.10.132/api/Accounts/1
http://102.10.10.132/api/Accounts/ {accountId}
@Path:所有在網址中的參數(URL的問號前面),如:
http://102.10.10.132/api/Accounts/ {accountId}
@Query:URL問號後面的參數,如:
http://102.10.10.132/api/Comments?access_token= {access_token}
@QueryMap:相當於多個@Query
@Field:用於POST請求,提交單個數據
@Body:相當於多個@Field,以對象的形式提交
Tips
『肆』 在Android中使用retrofit時,怎樣獲取響應的頭信息
獲取方法
有兩種獲取Response Headers的方法
直接在定義介面是讓介面返回Retrofit的Response對象,
在Response對象中可以獲取到Headers
Interceptor必須在OkHttpClient構建時加入,
OKHttpClient的interceptors()方法返回的是一個不可編輯的列表,
如果對其進行修改操作,會產生UnSupportedOperationException。
『伍』 在Android中使用retrofit時,怎樣獲取響應的頭信息
有兩種獲取Response Headers(即響應的頭信息)的方法,第一種是直接在定義介面是讓介面返回Retrofit的Response對象,在Response對象中可以獲取到Headers。在構建Retrofit的APIService,在OkHttpClient中加入Interceptor,用以攔截請求和響應獲取請求頭和響應頭。此方法可用於Retrofit2和OKHttp3.