- 通过Retrofit2 拦截器获取到请求参数和响应内容
- 兼容了POST和GET请求
- 返回值以JSON格式展示
1、Retrofit2中使用自定义的日志拦截器:
@Override
public void okHttpClient(OkHttpClient.Builder okHttpClient) {
okHttpClient.connectTimeout(5000, TimeUnit.MILLISECONDS)
.writeTimeout(60000, TimeUnit.MILLISECONDS)
.readTimeout(60000, TimeUnit.MILLISECONDS)
.addInterceptor(chain -> {
Request.Builder builder = chain.request().newBuilder();
AccountBean bean = MainApplication.getInstance().getAccountBean();
builder.addHeader("user_id", bean.getUserCardNum());//身份证号码
return chain.proceed(builder.build());
});
okHttpClient.addInterceptor(new HttpLogReportInterceptor());//统一日志拦截器
}
2、HttpLogReportInterceptor.java 源码:
import android.net.Uri;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
public class HttpLogReportInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
int httpCode = response.code();//获取响应码
String url = request.url().toString();
String requestParam = "";
switch (request.method().toLowerCase()) {
case "post":
requestParam = getRequestParams4Post(request);//请求参数
break;
case "get":
requestParam = getRequestParams4Get(request.url().toString());
break;
}
String jsonStr = getResponseContent(response);
int code = -1;//业务逻辑的code
// 1、接口调用成功(有响应)
// 2、业务逻辑执行完成
try {
HttpBaseResult baseResult = new Gson().fromJson(jsonStr, HttpBaseResult.class);
code = baseResult.getStatus();
// LegoLog.d("业务逻辑 Code:" + code);
} catch (Exception e) {
LegoLog.w(e.getMessage());
}
if (httpCode == 200 && (code == 200)) {
// 1、接口调用成功(有响应)
// 2、业务逻辑执行完成
} else {
LegoLog.d("Http Code:" + httpCode + ";;业务code:" + code);
}
return response;
}
private String getRequestParams4Get(String url) {
Uri uri = Uri.parse(url);
JsonObject requestJson = new JsonObject();
for (String paramKey : uri.getQueryParameterNames()) {
String paramValue = uri.getQueryParameter(paramKey);
requestJson.addProperty(paramKey, paramValue);
}
return requestJson.toString();
}
/**
* 获取POST请求参数
*/
private String getRequestParams4Post(Request request) throws IOException {
if (request.body() != null && HttpContentTypeUtil.isParseable(request.body().contentType())) {
return parseRequestParams4Post(request);
}
// 说明:multipart/form-data 需要特殊处理
return "";
}
/**
* 解析请求服务器的请求参数
*/
private static String parseRequestParams4Post(Request request) throws UnsupportedEncodingException {
try {
RequestBody body = request.body();
if (body == null) return "";
Buffer requestBuffer = new Buffer();
body.writeTo(requestBuffer);
Charset charset = StandardCharsets.UTF_8;
MediaType contentType = body.contentType();
if (contentType != null) {
charset = contentType.charset(charset);
}
String text = requestBuffer.readString(charset);
if (contentType != null && !"json".equals(contentType.subtype())) {
text = URLDecoder.decode(text, convertCharset(charset));
}
return TextUtil.jsonFormat(text);
} catch (IOException e) {
e.printStackTrace();
return "{\"error\": \"" + e.getMessage() + "\"}";
}
}
private static String convertCharset(Charset charset) {
String s = charset.toString();
int i = s.indexOf("[");
if (i == -1)
return s;
return s.substring(i + 1, s.length() - 1);
}
/**
* 获取返回值内容
*
* @param response
* @return
*/
private String getResponseContent(Response response) {
try {
//读取服务器返回的结果
// ResponseBody responseBody = response.newBuilder().build().body();
ResponseBody responseBody = response.body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // Buffer the entire body.
Buffer buffer = source.buffer();
//获取content的压缩类型
String encoding = response.headers().get("Content-Encoding");
//克隆服务器的响应内容()
Buffer cloneBuffer = buffer.clone();
//解析response content
return parseResponseContent(responseBody.contentType(), encoding, cloneBuffer);
} catch (IOException e) {
LegoLog.w(e.getMessage());
return "{\"error\": \"" + e.getMessage() + "\"}";
}
}
/**
* 解析服务器响应的内容
*
* @param contentType
* @param encoding 编码类型
* @param cloneBuffer 克隆后的服务器响应内容
* @return 解析后的响应结果
*/
private String parseResponseContent(MediaType contentType, String encoding, Buffer cloneBuffer) {
Charset charset = StandardCharsets.UTF_8;
if (contentType != null) {
charset = contentType.charset(charset);
}
if (encoding != null && encoding.equalsIgnoreCase("gzip")) {//content使用gzip压缩
return ZipUtil.decompressForGzip(cloneBuffer.readByteArray(), convertCharset(charset));//解压
} else if (encoding != null && encoding.equalsIgnoreCase("zlib")) {//content使用zlib压缩
return ZipUtil.decompressToStringForZlib(cloneBuffer.readByteArray(), convertCharset(charset));//解压
} else {//content没有被压缩
return cloneBuffer.readString(charset);
}
}
}
HttpBaseResult.java
public class HttpBaseResult<T> {
private int code;
private String msg;
private T data;
//...get/set
}
特别说明:
ResponseBody body = response.body();//获取响应体
// 由于ResponseBody内的bytes()、string()方法调用了closeQuietly方法,此方法会将ResponseBody内的数据源清除,所以仅获取一次内容。
byte[] bytes = body.bytes();//获取字节数组
由于ResponseBody内的 bytes()、string()方法调用了== Util.closeQuietly(source);==,此方法会将ResponseBody内的数据源清除,所以仅获取一次内容。