ps: 我寫這篇這是很晚了痴昧,也是怪我自己啊,一直以來拖拖拉拉的就是改不了,retrofit 看著好幾次了米丘,看完有些日子就記不清了剑令,也沒記錄下來,忘了都沒地方找去拄查。所以今天好好理一理 retrofit 吁津,注解的使用還是很有必要記記的,誰也不敢打包票自己不忘是不堕扶,尤其是我腺毫,我對于這可是有深刻的印象啊,16年那會(huì)完全不寫博客挣柬,看了好多東西潮酒,看完就忘,結(jié)果發(fā)現(xiàn)16年的收獲慘不忍睹啊邪蛔。
另外說一點(diǎn)急黎,寫博客真是對知識(shí)點(diǎn)的理解和記憶是大大的加深啊,所以大家總是說好記性不如爛筆頭呀
retrofit 集成侧到,簡單使用
- 添加依賴
// retrofit 依賴
compile 'com.squareup.retrofit2:retrofit:2.4.0'
compile 'com.squareup.retrofit2:converter-gson:2.4.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
- 編寫遠(yuǎn)程接口
retrofit 使用直接注解動(dòng)態(tài)生成遠(yuǎn)程請求 API 勃教,這讓我們專注于接口聲明,而不用去管理實(shí)現(xiàn)匠抗,既簡單又明了
public interface BlueService {
@GET("book/search")
Call<ResponseBody> getSearchBooks(@Query("q") String name,
@Query("tag") String tag, @Query("start") int start,
@Query("count") int count);
}
- 原生簡單請求
String baseUrl = "https://api.douban.com/v2/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.build();
BlueService blueService = retrofit.create(BlueService.class);
blueService.getSearchBooks("小王子", "", 0, 3)
.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
String message = response.body().string();
Log.d("AAA", "onResponse: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d("AAA", "onFailure: 聯(lián)網(wǎng)失敗");
}
});
注意肮试础:
- baseUrl 跟路徑必須以 “ / ” 結(jié)尾,現(xiàn)在強(qiáng)制要求了汞贸,不寫會(huì)報(bào)錯(cuò)
- response.body().string() 可以獲取原始的 response 數(shù)據(jù)(字符串)绳军,我們使用的 .string() 而不是 .toString() , toString 出來的 class 名字。同時(shí)返回參數(shù)數(shù)據(jù)類型我們必須使用 ResponseBody 這個(gè)才行矢腻,這是 okhttp3 里面的门驾,這樣才能拿到原始響應(yīng)體
- 這個(gè)寫法一般是獲取 json 轉(zhuǎn) bean 或是測試通不通用的,正常我們不這么用
- 添加 json 數(shù)據(jù)變換
String baseUrl = "https://api.douban.com/v2/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
BlueService blueService = retrofit.create(BlueService.class);
blueService.getSearchBooks("小王子", "", 0, 3)
.enqueue(new Callback<BookResponse>() {
@Override
public void onResponse(Call<BookResponse> call, Response<BookResponse> response) {
try {
BookResponse bookResponse = response.body();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<BookResponse> call, Throwable t) {
Log.d("AAA", "onFailure: 聯(lián)網(wǎng)失敗");
}
});
這個(gè)我們在 retrofit.build 時(shí)添加了類型轉(zhuǎn)換器多柑,就可以讓 retrofit 自動(dòng)幫我們轉(zhuǎn)換 json 了奶是,然后遠(yuǎn)程接口,callback 我們都可以直接使用具體的數(shù)據(jù)類型了竣灌。我們還是 try 一下保險(xiǎn)
- 添加 rxjava 支持聂沙,變換請求結(jié)果為 observable
public interface BlueService {
@GET("book/search")
Observable<BookResponse> getSearchBooks(@Query("q") String name,
@Query("tag") String tag, @Query("start") int start,
@Query("count") int count);
}
String baseUrl = "https://api.douban.com/v2/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
BlueService blueService = retrofit.create(BlueService.class);
blueService.getSearchBooks("小王子", "", 0, 3)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<BookResponse>() {
Disposable disposable;
@Override
public void onSubscribe(Disposable d) {
disposable = d;
}
@Override
public void onNext(BookResponse bookResponse) {
Log.d("AAA", "onNext: " + bookResponse.getBooks().size());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
disposable.dispose();
}
});
}
要注意 rxjava2 的支持和1不同,rxjava2 的支持請安上面的依賴添加
中間插一段 http 協(xié)議基礎(chǔ)
我也是個(gè)搬運(yùn)工初嘹,http 協(xié)議我摘一點(diǎn)作用明顯的及汉,大家看看,然后覺得不怎么懂就去專門看下削樊,我在下面會(huì)附上地址的
HTTP 的請求報(bào)文分為三個(gè)部分 請求行豁生、請求頭和請求體兔毒,格式如圖:
- 請求行
請求行(Request Line)分為三個(gè)部分:請求方法漫贞、請求地址和協(xié)議及版本甸箱,HTTP/1.1 定義的請求方法有8種:
- GET、POST迅脐、PUT芍殖、DELETE、PATCH谴蔑、HEAD豌骏、OPTIONS、TRACE隐锭,最常的兩種GET和POST
- RestFul 規(guī)范的接口的話會(huì)用到 GET窃躲、POST、DELETE钦睡、PUT蒂窒,分別對應(yīng)數(shù)據(jù)庫的增刪改查操作:
- PUT -> 增
- DELETE -> 刪
- POST -> 改
- GET -> 查
在了解請求地址之前,先了解一下URL的構(gòu)成:
所以我們在 retrofit 的 baseUrl 添加跟地址的行為就是添加 http 協(xié)議和主機(jī)地址
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
剩下的 http 基礎(chǔ)內(nèi)容還有很多荞怒,我就不復(fù)制了洒琢,大家看這里:你應(yīng)該知道的HTTP基礎(chǔ)知識(shí),一定要看哦褐桌,要不后面你會(huì)暈衰抑,有地方搞不明白的
- 請求頭
其中有一點(diǎn)我們一定要弄清楚的是 http 請求體類型,也就是我們會(huì)看到的 Content-Type
- Content-Type:application/json
表示這是提交的 json - Content-Type:application/x-www-form-urlencoded
表單提交 - Content-Type:multipart/form-data; boundary={boundary}
文件提交荧嵌,也叫模擬表單
重頭戲來啦呛踊,注解詳解
整篇文章的重點(diǎn)就在這啦,前面的都是浮云啦撮,初次使用的同學(xué)可能覺得有些繁瑣恋技,有些不好理解,但是對于有點(diǎn)水平的同學(xué)們來說就不叫事了不是逻族,所x以注解這個(gè)才是我們需要重點(diǎn)學(xué)習(xí)的蜻底,看了上面的 http 協(xié)議的部分知識(shí)點(diǎn),我們再去研究下 retrofit 的注解就不是那么撓頭了
1. 請求類型
請求類型是請求頭中的一個(gè)內(nèi)容聘鳞,寫在 header 里薄辅,字段是:Content-Type,是描述我們給服務(wù)器發(fā)送的數(shù)據(jù)采用什么格式發(fā)送抠璃,下面放個(gè)例子:
interface APIStore {
@Headers({"Content-Type: application/json","Accept: application/json"})
@POST ("vdyweb/ws/rest/Login")
Call<ResponseBody>getMessage(@Body RequestBody info);
}
大家看到在請求頭中添加了 Content-Type 字段的數(shù)據(jù)站楚,這里總結(jié)下有幾種請求方式啊,這點(diǎn)很重要的搏嗡,寫不對你的遠(yuǎn)程通訊就會(huì)不同窿春,或是服務(wù)器拿不到數(shù)據(jù)哦拉一。retrofit 已經(jīng)為我們封裝好了常用的請求方式,這里結(jié)合的說一下:
- 什么都不寫
什么都不寫表示傳遞參數(shù)沒有規(guī)范旧乞,發(fā)送過去的是二進(jìn)制流蔚润,傳值你得用 @Body 注解,服務(wù)器接受到的是二進(jìn)制流尺栖,然后可以轉(zhuǎn)成字符串按 json 解析數(shù)據(jù)嫡纠,不過一般我么不推薦這么寫。 - json 提交
json 的話我司現(xiàn)在就是用這種方法延赌,適合做 post 萬能請求接口除盏,不過在 RestFul 規(guī)范的今天, 不在推薦這么寫了挫以,我們也得讓后臺(tái)兄弟舒服不是者蠕。所以我們在 retrofit 找不到這個(gè)注解,就是因?yàn)椴煌扑]這種寫法了掐松, 下面是自己寫的方式踱侣,這里只是接口聲明,詳細(xì)在后面
interface APIStore {
@Headers({"Content-Type: application/json","Accept: application/json"})
@POST ("vdyweb/ws/rest/Login")
Call<ResponseBody>getMessage(@Body Book book);
}
@Body 的數(shù)據(jù)對象甩栈,Retrofit2 會(huì)自動(dòng)轉(zhuǎn)成 Gson 字符串發(fā)送
- get 方式
get 方式很特殊泻仙,大家都知道 get 請求方式很特殊,把一切都拼接在 url 地址中量没,所以沒那么復(fù)雜玉转, Content-Type 不用設(shè)置 - 表單提交
表單提交,數(shù)據(jù)都以 key—value 的形式存在請求體中殴蹄,服務(wù)器獲取參數(shù)也是用 key—value 的形式去拿數(shù)據(jù)究抓,作為最常使用的提交方式,retrofit 已經(jīng)給我們封裝好了袭灯,專門有一個(gè)字段
@FormUrlEncoded
Observable<BookResponse> getSearchBooks(@Query("q") String name);
自己寫的話就是
@Headers("Content-Type:application/x-www-form-urlencoded")
Observable<BookResponse> getBooks();
- 模擬表單
在表單提交的基礎(chǔ)上可以添加文件數(shù)據(jù)刺下,retrofit 也給我們封裝好了
@Multipart
Observable<BookResponse> getBooks();
自己寫的話就是
@Headers("Content-Type:multipart/form-data; boundary={boundary}")
Observable<BookResponse> getBooks();
boundary 部分可寫可不些,我看有人不寫 boundary 也沒事稽荧,boundary=xxxxxxx橘茉,xxxxxx規(guī)定了請求體中的內(nèi)容分隔符
-
文檔相關(guān)資料
retrofit3.png
2. 請求方法
請求方法上面 http 基礎(chǔ)應(yīng)說過了,這個(gè)不難理解姨丈,需要注意的是 restFul 規(guī)范下的部分:
* PUT -> 增
* DELETE -> 刪
* POST -> 改
* GET -> 查
這里要提一下 http 這個(gè)請求方法畅卓,HTTP注解則可以代替任意一個(gè)青谷去方法,有3個(gè)屬性:method蟋恬,path翁潘,hasBody,下面是例子:
public interface BlogService {
/**
* method 表示請的方法歼争,不區(qū)分大小寫
* path表示路徑
* hasBody表示是否有請求體
*/
@HTTP(method = "get", path = "blog/{id}", hasBody = false)
Call<ResponseBody> getFirstBlog(@Path("id") int id);
}
3. 數(shù)據(jù)接收類型
在 http 協(xié)議中可以指定接受服務(wù)器返回?cái)?shù)據(jù)的類型拜马,這個(gè)一般我們不用自己去設(shè)置渗勘,retrofit 默認(rèn)就是 json 格式的,但是自己也可以設(shè)俩莽,使用的是上面可以看到的 Accept 這個(gè)字段
@Headers({"Content-Type: application/json","Accept: application/json"})
寫在 head 請求頭了旺坠,看到這大家可以發(fā)現(xiàn),這些設(shè)置除了 get/post 之外豹绪,所有的請求設(shè)置都是寫在請求頭里的价淌,請求頭就是干這事的申眼,類似于我們常用的 config 瞒津,包裹配置參數(shù)和一些通用參數(shù)。
retrofit 還提供了 @Streaming 這個(gè)注解括尸,我們接收的數(shù)據(jù)不再是 json 的了巷蚪,而是一個(gè)二進(jìn)制輸入流。
@Streaming
4. 傳參相關(guān)參數(shù)
retrofit 用來在不同請求方法中傳遞參數(shù)的注解都在上面了濒翻,單說沒意思屁柏,結(jié)合 get / post 和請求不同的數(shù)據(jù)來說最簡單明了,容易懂有送。
5. get 傳參詳解
@GET("xxxUrl")
Observable<User> getUserInfo(
@Part("xxxUrl") String userUrl,
@Query("userid") int id,
@QueryMap Map<String, String> options,
@Query("list") List<String> options2);
可以看到 get 可以接受4種傳參注解:
- @Part -1
用來替換具體的 utl 路徑的淌喻,一般我們都是直接就寫 url 地址了,這里通過 @Part 提供一種動(dòng)態(tài)傳入 url 地址方式雀摘,@Part 注解是所有請求方法通用的裸删。 - @Part -2
上面的 @Part 寫法是整體替換具體的 URL 請求,其實(shí)要是后臺(tái)同學(xué)的 restFul API 寫的規(guī)范的話阵赠,我們請求涯塔,操作數(shù)據(jù)的 URL 也是可以做到動(dòng)態(tài)的,不是費(fèi)的一個(gè)接口寫一個(gè)固定的地址給我們清蚀。這時(shí) @Part 可以用來實(shí)現(xiàn)動(dòng)態(tài)替換 URL 中參數(shù)的事匕荸,使用 {“xxx”} 來標(biāo)記 URL 中可變的部分,下面就是一個(gè)例子:
@GET("book/{id}")
Observable<User> getBook(@Part("id") String id);
- @Query
傳單個(gè)參數(shù)枷邪,Query("userid") 里面的字符串是 key榛搔,后面指定 value 的類型 - @QueryMap
可以接受多個(gè)參數(shù),所有參數(shù)直接寫在 map 里 - Query("list")
get 方式支持直接傳入一個(gè)集合东揣,可以看到其實(shí)和我們單個(gè)傳參一樣践惑,只不過區(qū)別是接收的數(shù)據(jù)是單個(gè)對象,還是一個(gè)集合對象
6. post 傳參詳解
@POST("xxxUrl")
Observable<User> getUserInfo(
@Field("userid") int id,
@FieldMap Map<String, String> options,
@Field("list") List<String> options2);
post 傳參其實(shí)和 get 差不多救斑,卻別不多童本,一個(gè)是 query ,一個(gè)是 field
- @Field
傳單個(gè)參數(shù)脸候,和 @Query 一樣 - @FieldMap
傳多個(gè)數(shù)據(jù) - @Field("list")
同樣支持直接傳遞集合數(shù)據(jù)類型 - @POST
@POST 除了get 都能用穷娱,用來傳遞一個(gè)數(shù)據(jù)對象绑蔫,服務(wù)器按 stream 流的方式接收數(shù)據(jù)
@POST("name")
Observable<User> getName(@Body Book book);
7. 上傳文件
上傳文件一直是個(gè)有問題的地方,不管是 Xutils泵额,okhttp配深,retrofit 都有不是很明確的地方,這里就能看出網(wǎng)絡(luò)基礎(chǔ)是多么重要嫁盲,有時(shí)候你寫完之后篓叶,服務(wù)器接收不到參數(shù),或是問你發(fā)的數(shù)據(jù)用的什么類型羞秤,我怎么接受缸托,你都回答不上來,這個(gè)很尷尬不是瘾蛋,我是遇到過俐镐,還好后臺(tái)的兄弟沒打我臉,哈哈哈哈.......
不看我寫的哺哼,看看這些文章也是可以的:
有一點(diǎn)我們要說,表單提交的時(shí)候參數(shù)的編碼問題 enctype屬性取董。enctype:規(guī)定了form表單在發(fā)送到服務(wù)器時(shí)候編碼方式棍苹,他有如下的幾個(gè)值:
- application/x-www-form-urlencoded
默認(rèn)值,不寫就是這個(gè)茵汰,retrofit 的表單默認(rèn)也是這個(gè)枢里,不能用來傳文件,也就是二進(jìn)制數(shù)據(jù) - multipart/form-data
所有的數(shù)據(jù)以二進(jìn)制流發(fā)送 - application/otcet-stream
很奇怪经窖,我查了查是八進(jìn)制.........這個(gè)恕我真的不知道為啥有二進(jìn)制不用坡垫,去用八進(jìn)制 - text/plain
純文本格式
在帶有 file 的表單提交中:
- file 只能用流的形式上傳
- 可以用:multipart/form-data / application/otcet-stream 這2種流上傳,差別估計(jì)是后臺(tái)接受數(shù)據(jù)的 API 不同画侣。
- 文本參數(shù)可以用流的方式上傳冰悠,也可以用文本格式上傳
- 可以使用 multipart/form-data 這樣后臺(tái)用流接數(shù)據(jù),getParame 拿不到數(shù)據(jù)的配乱。
- 最好用 text/plain 文本格式傳溉卓,這樣后臺(tái)獲取數(shù)據(jù)和原來的方式相同。
好了看過這些搬泥,我們心里總算是對這些彎彎繞的東西有些初步了解了桑寨,再去和后臺(tái)溝通也大概知道怎么說了,查資料也知道去找什么東東了
@Multipart
@POST("upload")
Call<ResponseBody> uploadMultipleFiles(
@Part("description") RequestBody description,
@PartMap Map<String, RequestBody> options
@Part MultipartBody.Part file1,
@Part MultipartBody.Part file2);
這是一個(gè)帶其他參數(shù)的文件上傳 API 忿檩,大家注意看注解如何使用尉尾,這個(gè)是固定的,大家背下來就行燥透。期中 @Part("description") 里面的字符串是普通文本參數(shù)的 key
我們來看看重點(diǎn)的 java 代碼:
- 創(chuàng)建文本參數(shù)
注意這里我用的是 text/plain 發(fā)送文本參數(shù)沙咏,用 multipart/form-data 二進(jìn)制的方式也可以的
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), "文本參數(shù)");
- 創(chuàng)建 file 參數(shù)
File imageFile = new File("一張圖片");
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile);
MultipartBody.Part data = MultipartBody.Part.createFormData("file", imageFile.getName(), requestBody);
- 文件數(shù)據(jù)傳入 map 集合中的寫法
可能我們的接口是這樣的
@POST("NewsServlet")
@Multipart
Call<ResponseBody> testFileUpload3(@PartMap Map<String, RequestBody> map);
所有參數(shù)都放在這個(gè)集合中辨图,集合參數(shù)的放置如下,注意 file 類型的參數(shù)的 key 要包含 file 的name 進(jìn)去肢藐,需要自己拼接字符串的
NewsService newsService = createRetrofit().create(NewsService.class);
Map<String, RequestBody> fileUpload3Args = new HashMap<>();
MediaType textType = MediaType.parse("text/plain");
RequestBody name = RequestBody.create(textType, "txy");
RequestBody age = RequestBody.create(textType, "18");
fileUpload3Args.put("name", name);
fileUpload3Args.put("age", age);
//構(gòu)建要上傳的文件
File file = new File(Environment.getExternalStorageDirectory(), "paoche1.jpg");
RequestBody requestFile =
RequestBody.create(MediaType.parse("application/otcet-stream"), file);
fileUpload3Args.put("fileUploader\"; filename=\"paoche3.jpg",requestFile);
Call<ResponseBody> answers = newsService.testFileUpload3(fileUpload3Args)
上傳文件基本就是這些了故河,這塊容易忘,容易混吆豹,記下來非常有必要的鱼的。
8. 上傳圖片
上傳圖片看這篇也行,總結(jié)的也很好痘煤,比我全面一點(diǎn):
圖片也是文件凑阶,但是為啥要單獨(dú)拿出來說呢,因?yàn)閳D片有自己單獨(dú)的數(shù)據(jù)格式 : image/png
RequestBody photoRequestBody = RequestBody.create(MediaType.parse("image/png"), imageFile);
MultipartBody.Part photo = MultipartBody.Part.createFormData("上傳的key", "文件名.png", photoRequestBody);
9. 添加請求頭參數(shù)
請求頭參數(shù)我們可以在網(wǎng)絡(luò)請求的 API 接口里寫速勇,也可以給 okhttp 添加一個(gè)攔截器進(jìn)來晌砾,在請求構(gòu)建完成坎拐,發(fā)送前的那一刻攔截烦磁,然后添加請求頭數(shù)據(jù),這樣適合添加動(dòng)態(tài)可變參數(shù)
- @Headers 添加靜態(tài)請求頭參數(shù)
public interface BlueService {
@Headers("Cache-Control: max-age=640000")
@Headers({
"Accept: application/vnd.yourapi.v1.full+json",
"User-Agent: Your-App-Name"
})
@GET("book/search")
Call<BookSearchResponse> getSearchBooks(@Query("q") String name,
@Query("tag") String tag, @Query("start") int start,
@Query("count") int count);
}
注意添加一條和多條的區(qū)別
- @Header 添加動(dòng)態(tài)請求頭參數(shù)
public interface BlueService {
@GET("book/search")
Call<BookSearchResponse> getSearchBooks(
@Header("Content-Range") String contentRange,
@Query("q") String name, @Query("tag") String tag,
@Query("start") int start, @Query("count") int count);
}
- 添加攔截器動(dòng)態(tài)添加請求頭參數(shù)
public class HeadInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("User-Agent", "Your-App-Name")
.header("Accept", "application/vnd.yourapi.v1.full+json")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
}
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new HeadInterceptor ())
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
添加 header 參數(shù) Request 提供了兩個(gè)方法:
- header(key, value)
如果有重名的將會(huì)覆蓋 - ddHeader(key, value)
允許相同 key 值的 header 存在
10. 為某個(gè)請求設(shè)置完整的URL
有個(gè)別的請求的 URL 不用用的我們基礎(chǔ)的 baseurl 的哼勇,怎么辦都伪,我們可以使用 @Url 注解來忽略 baseurl 的
@GET
public Call<ResponseBody> profilePicture(@Url String url);
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://your.api.url/");
.build();
BlueService service = retrofit.create(BlueService.class);
service.profilePicture("https://s3.amazon.com/profile-picture/path");
json 上傳的再次說明
json 上傳數(shù)據(jù)不推薦,但是有時(shí)候我們真的需要积担,這里多記錄一下找到的東西陨晶。
json 除了我們直接 @Body Book book 直接寫具體的數(shù)據(jù)類型的做法,我們也可以使用 RequestBody 來寫
public interface PostRoute {
@Headers({"Content-Type: application/json","Accept: application/json"})
@POST("api/FlyRoute/Add")
Call<FlyRouteBean> postFlyRoute(@Body RequestBody route)RequestBody
}
// 先 json 一個(gè)字符串?dāng)?shù)據(jù)出來
Book book= new Book ();
Gson gson=new Gson();
String route = gson.toJson(book);
// 我們生成一個(gè) RequestBody 請求對象出來
PostRoute postRoute=retrofit.create(PostRoute.class);
RequestBody body=RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),route);
Call<Book> call=postRoute.postFlyRoute(body);
添加日志管理
這個(gè)是 okhttp 的部分帝璧,但是呢我們不打算專門寫一個(gè) okhttp 的入了先誉,在 retrofit 中我們已經(jīng)充分使用了 okhttp 了,索性就一起寫了
retrifit 又開源的日志攔截器的烁,要不我們就自己寫攔截器打印日志褐耳,不過肯定大的不如直接誒個(gè)開源的全啊渴庆。
添加依賴
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
使用
// 創(chuàng)建日志攔截器對象出來
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
//包含header、body數(shù)據(jù)
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
// 添加日志攔截器到 okhttp 對象中
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build();
// 把 okhttp 對象添加到 retrofit 對象中
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
打印樣式圖:
注意里面 --> 刃滓、<-- 箭頭的方向:
- --> 表示我們請求的內(nèi)容,包括請求頭參數(shù)耸弄,請求信息等,這里我們是最簡單的 get 請求所以表現(xiàn)不出來
- <-- 是我們接受到的內(nèi)容计呈,包括接受數(shù)據(jù)形式
- interceptor 有幾個(gè)級別僚饭,我們用 body 就行胧砰,body 會(huì)代印包括頭在內(nèi)的所有信息
facebook 網(wǎng)絡(luò)調(diào)試器 Stetho
我還看到有一位朋友提到 facebook 開源了 Stetho 網(wǎng)絡(luò)監(jiān)測工具,試了試我沒成功尉间,有興趣的朋友請看:使用OkHttp高效開發(fā)調(diào)試
其他內(nèi)容
- retrofit 對于 https 的支持
這塊我現(xiàn)在也是看看,沒實(shí)踐過
對于 https 證書有兩種策略:
根據(jù)自己的證書服務(wù)器來配置,達(dá)到一對一的效果眠副,每個(gè)商業(yè)app都應(yīng)該有自己的證書設(shè)置画切,這樣能保證訪問的安全性。
在 okhttp 中設(shè)置信任所有證書囱怕,參考:okhttp3證書解決方式
-
請求加密
我項(xiàng)目中加密是用 MD5 把字符串里面的參數(shù)算一下霍弹,然后添加到請求頭里,服務(wù)器拿到后也計(jì)算一下然后核對 MD5 加密字段娃弓,無誤后再去執(zhí)行典格。-
Retrofit 2.0 詳解(三)報(bào)文加解密 攔截器(Interceptor)
這個(gè)思路是給獲取請求體字符串,添加加密字段 - Retrofit 2.0 超能實(shí)踐(一)台丛,完美支持加密Https傳輸
-
Retrofit 2.0 詳解(三)報(bào)文加解密 攔截器(Interceptor)
-
下載文件