Retrofit2.0和它的攔截器們
之前已經講過了Retrofit2.0的初步認識,不是很清楚的同學可以參看我的文章連結:
Retrofit2.0初識:http://blog.csdn.net/burn_yourself/article/details/71799253
一般的,我們在寫網路通訊的時候,log除錯是必須的,那麼本篇文章就來講講 Retrofit2.0 和 它的 攔截器們,主要包括以下幾方面:
1. Header 攔截器
2. Cache 攔截器
3.log 攔截器
那麼,下面就一一講述新增。
首先,還是需要新增網路許可權,由於快取攔截器,涉及到網路狀態,於是還要多新增一個網路狀態許可權,本篇涉及到的許可權有:
<uses-permission android:name="android.permission.INTERNET" />
<!-- 獲取運營商資訊,用於支援提供運營商資訊相關的介面 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
app 的 gradle 中新增包的引用:
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
注意,由於retrofit2.0 本身就是對okhttp3的一個封裝,所以不必再新增對於okhttp3.X 的引用
由於Retrofit2.0中並沒有對於攔截器的處理,於是還是得在 OKhttp 中去處理攔截的問題,然後將 okhttp 物件 add 到 Retrofit 初始化的程式碼中。
大概思路如此,首先貼出 Retrofit2.0 通訊大致流程,還是以 retrofit2.0 中 獲取簡訊驗證碼為例:
1.宣告api:
public interface ApiService<T>{
//註冊時獲取簡訊驗證碼
@POST("api/login/pushSms")
@FormUrlEncoded
Call<ApiResponse<SmsCode>> postSms(@FieldMap Map<String, String> map);
}
2.寫Retrofit物件,並配置網路:
package com.test.http.retrofit;
import com.test.http.interceptor.CacheInterceptor;
import com.test.http.interceptor.HeaderInterceptor;
import com.test.util.LogUtil;
import java.io.File;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by Admin on 2017/5/12.
*/
public class HttpClient{
public ApiService mApiService;
private HttpClient() {
Cache cache = new Cache(new File(BuildConfig.PATH_CACHE), BuildConfig.DEFAULT_CACHE_SIZE);
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addInterceptor(new HeaderInterceptor())//設定Header
.addNetworkInterceptor(new CacheInterceptor())//設定快取
.addInterceptor(new CacheInterceptor())
.cache(cache)
.connectTimeout(BuildConfig.DEFAULT_CONNECT_TIMEOUT, TimeUnit.SECONDS)//設定連線超時時間
.readTimeout(BuildConfig.DEFAULT_READ_TIMEOUT, TimeUnit.SECONDS)//設定讀取超時時間
.writeTimeout(BuildConfig.DEFAULT_WRITE_TIMEOUT, TimeUnit.SECONDS)//設定寫的超時時間
.retryOnConnectionFailure(true);//錯誤重連
//除錯模式列印Log日誌
if (BuildConfig.DEBUG) {
builder.addInterceptor(new LoggingInterceptor());
}
OkHttpClient client=builder.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
// .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
mApiService = retrofit.create(ApiService.class);
}
private static class HttpClientHolder {
private static final HttpClient INSTANCE = new HttpClient();
}
public static HttpClient getInstance() {
return HttpClientHolder.INSTANCE;
}
public ApiService getApiService() {
return mApiService;
}
}
activity中呼叫與接收:
private void send(Map<String,String>map){
HttpClient.getInstance().getApiService().postSms(map).enqueue(new Callback<ApiResponse<SmsCode>>() {
@Override
public void onResponse(Call<ApiResponse<SmsCode>>call, Response<ApiResponse<SmsCode>>response) {
int code=response.code();
ApiResponse apiResponse=response.body();
SmsCode sms= (SmsCode) apiResponse.getData();
Log.e(TAG, "sms: "+sms.getStatus());
}
@Override
public void onFailure(Call call, Throwable t) {
Log.e(TAG, "t"+t.getMessage());
}
});
}
大家細心的話會發現 類 HttpClient 中已經新增得有 攔截器了,HeaderInterceptor,CacheInterceptor,LoggingInterceptor.
攔截器都要實現 Interceptor 介面,首先看 HeaderInterceptor 是怎麼實現的
/**
* Created by Admin on 2017/5/13.
* header攔截器,對Header統一處理,涉及到header加密的也在此處理
*/
public class HeaderInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
//處理業務邏輯,可以對header統一處理,涉及到header加密的也在此處理
//......
request = builder.build();
return chain.proceed(request);
}
}
然後介紹的是 CacheInterceptor :
package com.test.http.interceptor;
import com.test.http.retrofit.BuildConfig;
import com.test.util.NetUtil;
import java.io.IOException;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by Administrator on 2016/11/3.
* 快取攔截器
*/
public class CacheInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!NetUtil.isNetworkConnected()) {//沒網強制從快取讀取(必須得寫,不然斷網狀態下,退出應用,或者等待一分鐘後,就獲取不到快取)
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (NetUtil.isNetworkConnected()) {//有網情況下,從伺服器獲取
int maxAge = BuildConfig.DEFAULT_COOKIE_NETWORK_TIME;
// 有網路時, 快取最大儲存時長為60s
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.removeHeader("Pragma")
.build();
} else {//沒網情況下,一律從快取獲取
// 無網路時,設定超時為30天
int maxStale = BuildConfig.DEFAULT_COOKIE_NO_NETWORK_TIME;
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.removeHeader("Pragma")
.build();
}
return response;
}
}
最後介紹我們的 LoggingInterceptor,其實個人認為 LoggingInterceptor 還是比較重要的,Retrofit2.0 中log攔截器的實現有兩種方式,一種是自定義,另一種是呼叫 okhpp中自帶的 log攔截器,
那麼,先介紹 LoggingInterceptor 的實現:
/**
* Created by Admin on 2017/5/13.
* 自定義log列印攔截器
*/
public class LoggingInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
//這個chain裡面包含了request和response,所以你要什麼都可以從這裡拿
//=========傳送===========
Request request = chain.request();
long requestTime = System.currentTimeMillis();//請求發起的時間
HttpUrl requestUrl=request.url();
Connection requestConnection=chain.connection();
Headers requestHeaders=request.headers();
//打印發送資訊
LogUtil.e("===LoggingInterceptor===傳送==requestUrl="+requestUrl);
LogUtil.e("===LoggingInterceptor===傳送==requestConnection="+requestConnection);
LogUtil.e("===LoggingInterceptor===傳送==requestHeaders="+requestHeaders);
//=========接收===========
long responseTime = System.currentTimeMillis();//收到響應的時間
Response response = chain.proceed(chain.request());
ResponseBody responseBody = response.peekBody(1024 * 1024);
HttpUrl responseUrl=response.request().url();
String content = response.body().string();
Headers responseHeaders=response.headers();
long delayTime=responseTime-requestTime;
//列印接收資訊
LogUtil.e("=====LoggingInterceptor===接收==responseUrl="+responseUrl);
LogUtil.e("=====LoggingInterceptor===接收==responseHeaders="+responseHeaders);
LogUtil.e("=====LoggingInterceptor===接收==delayTime="+delayTime);
LogUtil.e("=====LoggingInterceptor===接收==content="+content);
return response;
}
}
這裡最需要注意的是 方法中 對 request 和 response 的獲取和處理
自定義 Log除錯類在 HttpClient 中的呼叫順序是 ,先對 okhttp。builder 做些其它基本配置,然後
除錯模式列印Log日誌
if (BuildConfig.DEBUG) {
builder.addInterceptor(new LoggingInterceptor());
}
最後,在retrofit中加入 okhttp物件
OkHttpClient client=builder.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
// .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
mApiService = retrofit.create(ApiService.class);
OKHttp 呼叫系統 Log列印的話,需要在 app。gradle 中新增引用:
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
然後在程式碼中這樣寫:
//呼叫系統log攔截器
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(
new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
LogUtil.e("=======message=="+message);
}
});
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(logging);
}
message中會打印出 通訊中各種詳細資訊。
最後,貼出 網路配置檔案程式碼:
/**
* Created by Admin on 2017/5/12.
* 網路通訊相關配置
*/
public class BuildConfig {
public static boolean DEBUG=true;
/**正試**/
private final static String RELEASE_URL = "";
/**測試**/
private static final String DEBUG_URL = "http://192.168.0.10/";
public final static String BASE_URL = BuildConfig.DEBUG ? DEBUG_URL : RELEASE_URL;
public static final int DEFAULT_CACHE_SIZE = 150 * 1024 * 1024; // 50 MiB
/*超時時間-預設10秒*/
public static final int DEFAULT_CONNECT_TIMEOUT = 20;
public static final int DEFAULT_READ_TIMEOUT = 20;
public static final int DEFAULT_WRITE_TIMEOUT = 20;
/*有網情況下的本地快取時間預設60秒*/
public static final int DEFAULT_COOKIE_NETWORK_TIME = 0;
/*無網路的情況下本地快取時間預設30天*/
public static final int DEFAULT_COOKIE_NO_NETWORK_TIME = 24 * 60 * 60 * 30;
public static final String PATH_DATA = MyApplication.getInstance().getCacheDir().getAbsolutePath() + File.separator + "data";
public static final String PATH_CACHE = PATH_DATA + "/NetCache";
}
OK,今天關於 Retrofit2.0 攔截器就講到這裡,睡覺去了。大家有什麼疑問,或者我理解得有誤的地方,歡迎交流
相關推薦
Retrofit2.0和它的攔截器們
之前已經講過了Retrofit2.0的初步認識,不是很清楚的同學可以參看我的文章連結: Retrofit2.0初識:http://blog.csdn.net/burn_yourself/article/details/71799253 一般的,我們在寫網路通訊的時候,log
Retrofit2.0新增日誌攔截器列印URL一級返回資料
//定製OkHttp OkHttpClient.Builder httpClientBuilder = new OkHttpClient .Builder(); if (BuildConfig.DEBUG) {//釋出版本不再列印 // 日誌顯示級別
SpringMVC案例3----spring3.0項目攔截器、ajax、文件上傳應用
his water aop pro 文件夾 創建 adapt 後綴 實現 依然是項目結構圖和所需jar包圖: 顯示配置文件hib-config.xml <?xml version="1.0" encoding=&qu
<head>標簽和它的小夥伴們
容器 hello script charset content 不同 基本 介紹 tro head標簽是HTML文檔中最基本的必須元素之一(body:對,還有我): <html> <head> <title>文檔的標題<
SSH開發 | 配合自定義註解 和 Stratus攔截器,實現 方法級粒度 用戶鑒權
struts OS action gin 所有 具體實現 getmethod red nal 1.提要 本文是 小小商城-SSH版的 細節詳解系列 之一,項目 github:https://github.com/xenv/S-mall-ssh 本文代碼大部分在 gith
springboot 2.0+ 自定義攔截器 靜態資源問題
per static index 進行 onf 自定義攔截器 tor gis css 之前項目的springboot自定義攔截器使用的是繼承WebMvcConfigurerAdapter重寫常用方法的方式來實現的.靜態文件不需要進行放行,springboot會自動幫你放行。
Retrofit2.0和RxJava2.0的簡單封裝
一、首先新增專案依賴: implementation "com.squareup.okhttp3:logging-interceptor:$var.loggingInterceptor"
Retrofit 和 rxjava2的簡單使用和封裝utils 和日誌攔截器
依賴*********注意網路許可權 //rxjava依賴 implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' implementation 'io.reactivex.rxjava2:rxjava:2
Java過濾器和SpringMVC攔截器之間的關係與區別
由於最近做的專案中有一部分是介面遠端呼叫,用到了接入許可權和業務許可權的鑑定,需要採用SpringMVC的攔截器,以前用Struts2的時候用過攔截器,而SpringMVC的攔截器功能之前沒研究過,所以這次來稍微研究一下,得出的結論是SpringMVC的攔截器和Struts2的攔截器原理幾乎是一模一樣的,
web工程過濾器和springMVC攔截器的一些總結
今天自己寫SSO(單點登入)發現一些問題的總結 1。因為原先有攔截器inteceptor,所以想著就直接用攔截器搞好了,後來發現不行, 原因是:工程預設是/訪問,是在web中配置預設的,並沒有呼叫任何方法(而攔截器是攔截方法的),所以無論我修改spring配置檔案,修
Novate:Retrofit2.0和RxJava的又一次完美改進加強(Tamic部落格 -CSDN)
作者/Tamic 前言 用過RxJava和Retrofit的朋友,用久了就會發現Retrofit說難不難,說簡不簡,對於實際專案中,單純的用Retrofit做請求庫,開發起來還是很多不便,必須請求頭和引數處理,API介面數目眾多時的處理,
java專案許可權控制的理解和示例(基於shiro和傳統攔截器filter兩種方式)
1.概念 個人理解,許可權就是做到對不同使用者進行訪問限制,前提是保證在許可權需求設計範圍內不會出現非法也能訪問到不該訪問到的東西.因此按資料表設計將許可權分為:部門,使用者,角色,角色許可權中間表,許可權.(個人覺得一般專案可以考慮部門和角色合為一個),這
QtAndroid詳解(2):startActivity和它的小夥伴們
上一篇,“QtAndroid詳解(1):QAndroidJniObject”,我們做了好多好多準備工作,目的就是為使用 QtAndroid 名字空間裡的 startActivity() 方法呼叫 Android 系統功能奠定基礎。那這次呢,我們就要來研究如何使用 st
springboot 2.0+ 自定義攔截器
之前專案的springboot自定義攔截器使用的是繼承WebMvcConfigurerAdapter重寫常用方法的方式來實現的。以下WebMvcConfigurerAdapter 比較常用的重寫介面 /** 解決跨域問題 **/ public void addCo
Java自定義註解 和 springMVC攔截器 配合使用記錄系統操作日誌的案例
自定義註解的用法, 好多人不知道, 在這裡, 程式碼的註釋中, 我已經詳細的介紹了, 另外就是很多人不知道自定義註解如何使用, 這裡配合springMVC攔截器, 做一個非常實用的案例. 案例: 記錄系統操作的日誌 首先是定義註解: package cn.wxy.ssm
springmvc和struts2攔截器的簡單使用以及配置
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)throws Exception {System.out.println("進入方法之後。");}@
retrofit2.0使用攔截器Interceptor統一列印請求與響應的json
先新增依賴: compile ‘com.squareup.retrofit2:retrofit:2.1.0’ compile ‘com.squareup.retrofit2:converter-gson:2.1.0’ compile
微服務 SpringBoot 2.0(八):靜態資源和攔截器處理
一文搞清楚靜態資源和攔截器 —— Java面試必修 引言 接觸一個web專案,首先要確認的就是入口,所以靜態資源和攔截器在專案中是架構級的,在第五章我們整合了Thymeleaf模組,初次認識了SpringBoot對靜態資源的預設支援。今天我們來繼續學習Sp
OkHttp3.0(結合Retrofit2/Rxjava)利用攔截器實現全域性超時自動登入、新增統一引數
應用場景:1.服務端為了統計各個平臺、版本的使用情況,有時在介面中要求傳遞統一的諸如version(客戶端版本)、os(客戶端平臺android/iOS)、userId等引數,這時如果在介面中一一新增就比較繁瑣了,考慮做全域性處理;另外,一次登入成功後,
springMVC攔截器和過濾器總結
cal .org 文件 bat system als request ping blog 攔截器: 用來對訪問的url進行攔截處理 用處: 權限驗證,亂碼設置等 spring-mvc.xml文件中的配置: <beans xmlns="http://www.sprin