github地址:https://github.com/Dragonxwl/MyBasePro
1.此内容基于本人之前的文章
retrofit2 + okhttp3 + rxjava2 实现简单网络请求 https://www.jianshu.com/p/a36a51166fb2
2.本文章重点介绍一下拦截器的作用和用法
拦截器的作用就是再okhttp网络请求前后进行一些操作,例如输入日志,添加头,判断返回值进行统一处理
拦截器中如果是请求前需要进行操作,请在chain.proceed(request)方法前进行,此方法相当于发送网络请求过程,它的返回值Response相当于网络请求的返回值,如果需要对返回值进行判断,请对Response进行判断。
3.RetrofitClient
拦截器的添加位置
loggingInterceptor 日志拦截器 请求中各种状态和参数的返回okhttp3内自带拦截器
customInterceptor 实际是HeaderInterceptor 头部拦截器 自定义拦截器
getHttpErrorLogInterceptor() 实际是 HttpErrorLogInterceptor 请求错误日志拦截器 自定义拦截器
public void init(String baseUrl, Interceptor customInterceptor) {
...
mOkHttpClient = new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)// 日志拦截器
.addInterceptor(customInterceptor)// 头部拦截器
.addInterceptor(getHttpErrorLogInterceptor())// 请求错误日志拦截器
.build();
...
}
// 请求错误日志拦截器
public HttpErrorLogInterceptor getHttpErrorLogInterceptor() {
HttpErrorLogInterceptor httpErrorLogInterceptor = new HttpErrorLogInterceptor(new HttpErrorLogInterceptor.Logger() {
@Override
public void log(JSONObject json) {
}
@Override
public void sendError(@NonNull JSONObject json) {
}
});
return httpErrorLogInterceptor;
}
4.拦截器的顺序
mOkHttpClient = new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)// 日志拦截器
.addInterceptor(customInterceptor)// 头部拦截器
.addInterceptor(getHttpErrorLogInterceptor())// 请求错误日志拦截器
.build();
基于上面的加载顺序,实际在请求前先执行loggingInterceptor 中 chain.proceed(request) 方法前的操作,然后执行的是
customInterceptor 中 chain.proceed(request) 方法前的操作,然后执行的是
HttpErrorLogInterceptor 中 chain.proceed(request) 方法前的操作,返回值先执行loggingInterceptor中 chain.proceed(request) 方法后的操作,然后执行的是
customInterceptor 中 chain.proceed(request) 方法后的操作,然后执行的是
HttpErrorLogInterceptor 中 chain.proceed(request) 方法后的操作。
5.自定义拦截器 方法类
头部拦截器
此拦截器主要是为了添加请求头
public class HeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder builder = originalRequest.newBuilder();
builder.addHeader("Content-Type", "application/json");
builder.addHeader("request-id", StringUtils.getUUID());
//设置token
if (!noTokenList.contains(originalRequest.url().toString().replace(Application.GetHost(),""))) {
String token = ACConfig.getInstance().getAccessToken();
if (!TextUtils.isEmpty(token)) {
builder.addHeader("access-token", token);
LogUtil.LogI("HTTP-access-token:", token);
}
}
Request newRequest = builder.build();
return chain.proceed(newRequest);
}
}
// 请求错误日志拦截器
此拦截器的作用是,当网络请求返回的是错误的情况下,将此次网络请求从开始到结束所有步骤所有参数都保存到返回日志接口(log)和发送错误接口(sendError)。
public final class HttpErrorLogInterceptor implements Interceptor {
private static final Charset UTF8 = Charset.forName("UTF-8");
public interface Logger {
void sendError(JSONObject message);
/**
* A {@link Logger} defaults output appropriate for the current platform.
*/
void log(JSONObject message);
}
public HttpErrorLogInterceptor(Logger logger) {
this.logger = logger;
}
private final Logger logger;
@Override
public Response intercept(Chain chain) throws IOException {
JSONObject json = new JSONObject();
Request request = chain.request();
Headers headers = request.headers();
Response response;
long code = -1;
String method;
HttpUrl url;
try {
json.put("headersToStr", headers.toString());
} catch (Exception e) {
e.printStackTrace();
}
// 遍历header
JSONObject headerJson = new JSONObject();
for (int i = 0, count = headers.size(); i < count; i++) {
String name = headers.name(i);
try {
headerJson.put(name, headers.value(i));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
json.put("headers", headerJson.toString());
} catch (Exception e) {
e.printStackTrace();
}
// 获取 请求方式 请求路径
method = request.method();
url = request.url();
try {
json.put("method", method);
json.put("url", request.url());
} catch (Exception e) {
e.printStackTrace();
}
// 获取参数
if (method.equals("POST") || method.equals("PUT")) {
RequestBody body = request.body();
if (body != null) {
if (body instanceof FormBody) {
JSONObject paramsJson = new JSONObject();
for (int i = 0; i < ((FormBody) body).size(); i++) {
try {
paramsJson.put(((FormBody) body).name(i), ((FormBody) body).value(i));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
json.put("params", paramsJson.toString());
} catch (Exception e) {
e.printStackTrace();
}
} else {
Buffer buffer = new Buffer();
body.writeTo(buffer);
String oldParamsJson = buffer.readUtf8();
try {
json.put("params", new JSONObject(oldParamsJson));
} catch (Exception e) {
e.printStackTrace();
}
}
}
} else if (method.equals("GET")) {
JSONObject paramsJson = new JSONObject();
for (int i = 0; i < url.querySize(); i++) {
try {
paramsJson.put(url.queryParameterName(i), url.queryParameterValue(i));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
json.put("params", paramsJson.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
// 记录请求开始时间
long startNs = System.nanoTime();
try {
response = chain.proceed(request);
} catch (Exception e) {
// 请求发生错误
try {
json.put("ErrorMessage", e);
} catch (Exception e1) {
e1.printStackTrace();
}
// 发送错误日志
logger.sendError(json);
throw e;
}
// 获取请求时间
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
code = response.code();
try {
json.put("code", response.code());
json.put("tookMs", tookMs + "毫秒");
} catch (Exception e1) {
e1.printStackTrace();
}
// 获取请求 返回body
ResponseBody responseBody = response.body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
JSONObject bodyJson = null;
try {
bodyJson = new JSONObject(buffer.clone().readString(UTF8));
} catch (Exception e) {
e.printStackTrace();
}
try {
json.put("body", bodyJson.toString());
} catch (Exception e1) {
e1.printStackTrace();
}
int errorCode = -1;
if (bodyJson != null) {
try {
errorCode = bodyJson.getInt("errorCode");
//服务端80080001~80080099错误
if (errorCode >= 80080001 && errorCode <= 80080099) {
serverErrorEvent(bodyJson.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 上传条件 code 不等 200 或者 errorCode 不等于0
if (code != 200 || errorCode != 0) {
logger.sendError(json);
} else {
logger.log(json);
}
return response;
}
/**
* 服务端80080001~80080099错误
*
* @param bodyJsonStr
*/
private void serverErrorEvent(String bodyJsonStr) {
ServerErrorBean serverErrorBean = GsonUtil.parseJsonWithGson(bodyJsonStr, ServerErrorBean.class);
//服务端80080001~80080099错误
if (serverErrorBean != null && serverErrorBean.data != null) {
}
}
}