Retrofit 請求失敗問題填坑記錄
本文主要列舉一些遇到的retrofit 請求的問題,作為記錄。
關於Retrofit的註解介紹可移步另一篇文章總結:Retrofit 2.0全部註解及注意事項
文章目錄
- 問題一:@Field parameters can only be used with form encoding
- 問題二:@Body parameters cannot be used with form or multi-part encoding.
問題一:@Field parameters can only be used with form encoding
使用post請求且引數註解為@Field時會報此錯誤
@POST("news/list")
Call<NewsData> getNewsData(@Field("key") String key);
錯誤原因是:
@Field引數只能用在表單編碼(form encoding),即Content-Type: application/x-www-form-urlencoded,而預設的格式是Content-Type: application/json; charset=UTF-8;
解決方法是:
新增url編碼方式的註解:@FormUrlEncoded
@FormUrlEncoded @POST("news/list") Call<NewsData> getNewsData(@Field("key") String key);
@FormUrlEncoded註解會將url編碼轉為form格式即Content-Type: application/x-www-form-urlencoded。
但是這樣可能還會失敗,因為可能會產生一個新的問題:
一般後臺介面設計的接收引數的編碼格式是json的即Content-Type: application/json; charset=UTF-8,而我們傳過去的url格式為form的,就會造成url無法識別,返回錯誤編碼415,代表是引數錯誤。那我們會想使用header註解指定content-type為json應該可以了吧,然而嘗試後會報400的錯誤,所以@FormUrlEncoded註解不止是改變一個content-type那麼簡單,原始碼裡還有很多和此註解相關的邏輯控制,想要具體深究的同學可以仔細跟一下原始碼。那這要如何解決呢?
最終解決方法為:
引數封裝使用@Body:
@POST("news/list")
Call<NewsData> getNewsData(@Body("key") String key);
如果是兩個以上引數就要封裝到一個bean中,這樣就可以解決。
如果引數只有一個或者兩個我們一定會覺得這樣做會很麻煩而且程式碼冗餘很難容忍,但是暫時沒有找到其他解決方法。
問題二:@Body parameters cannot be used with form or multi-part encoding.
錯誤原因:
其實錯誤資訊很明確,就是@Body標籤不能同時和@FormUrlEncoded、@Multipart標籤同時使用。
@FormUrlEncoded
@POST("/api/getUser")
Observable<String> getUserInfo(@Body User user);
檢視報錯位置原始碼如下:
if (isFormEncoded || isMultipart) {
throw parameterError(p, "@Body parameters cannot be used with form or multi-part encoding.");
}
這樣就一目瞭然了。