拦截指定http请求头,请求参数,请求方法,保存到本地
将拦截器添加到okhttp即可
一.LoggingInterceptor
package com.http.intercepter;
import android.os.Environment;
import android.util.Log;
import com.moan.bookwebserver.bookserverkit.momoapi.utils.AppExecutorUtils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import okhttp3.Headers;
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 LoggingInterceptor implements Interceptor {
private static final String SERVER_DATA = "serverData";
private AppExecutorUtils appExecutorUtils = null;
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
String url = request.url().toString();
boolean isNeedSave = url.endsWith("/sync/getAnnotation") || url.endsWith("/sync/getReadingInfo") || url.endsWith("/sync/uploadReaderAllModify")
|| url.endsWith("/bookcase/getBookCaseList");
if(isNeedSave) {
printInfo(request, response);
}
return response;
}
private void printInfo(Request request, Response response) {
// 通过当前时间创建Date对象
Date currentDate = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
String formattedDate = sdf.format(currentDate);
String logInfo = "***************************\r\n"+
"START HTTP->"+formattedDate
.concat("请求方法-->:")
.concat(request.method())
.concat(" ")
.concat(request.url().toString())
.concat(" \r\n ")
.concat("请求头-->:")
.concat(getRequestHeaders(request))
.concat(" \r\n ")
.concat("请求参数-->:")
.concat(getRequestParams(request))
.concat(" \r\n ")
.concat("返回结果-->:")
.concat(getResponseText(response))
.concat(" \r\n ")
.concat("END HTTP->");
// Log.e("xtt","LoggingInterceptor--请求方法-->:"+request.method());
// Log.e("xtt","LoggingInterceptor--请求Url-->:"+request.url().toString());
// Log.e("xtt","LoggingInterceptor--请求头-->:"+getRequestHeaders(request));
// Log.e("xtt","LoggingInterceptor--请求参数-->:"+getRequestParams(request));
// Log.e("xtt","LoggingInterceptor--返回结果-->:"+getResponseText(response));
appExecutorUtils = new AppExecutorUtils();
if(appExecutorUtils != null){
appExecutorUtils.cachedThreadPool().execute(() -> saveLogToFile(logInfo,SERVER_DATA));
}
}
private String getResponseText(Response response) {
String str = "Empty!";
try {
ResponseBody body = response.body();
if (body != null && body.contentLength() != 0) {
BufferedSource source = body.source();
source.request(Long.MAX_VALUE);
Buffer buffer = source.buffer();
MediaType mediaType = body.contentType();
if (mediaType != null) {
@SuppressWarnings("CharsetObjectCanBeUsed") Charset charset = mediaType.charset(
Charset.forName("UTF-8"));
if (charset != null) {
str = buffer.clone().readString(charset);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
private String getRequestParams(Request request) {
String str = "Empty!";
try {
RequestBody body = request.body();
if (body != null) {
Buffer buffer = new Buffer();
body.writeTo(buffer);
MediaType mediaType = body.contentType();
if (mediaType != null) {
@SuppressWarnings("CharsetObjectCanBeUsed") Charset charset = mediaType.charset(
Charset.forName("UTF-8"));
if (charset != null) {
str = buffer.readString(charset);
} else {
str = buffer.readUtf8();
}
} else {
str = buffer.readUtf8();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
private String getRequestHeaders(Request request) {
Headers headers = request.headers();
String str = "Empty!";
StringBuilder builder = new StringBuilder();
if (headers.size() > 0) {
for (int i = 0, count = headers.size(); i < count; i++) {
builder.append(headers.name(i) + ": " + headers.value(i)).append(" \r\n ");
}
return builder.toString();
} else {
return "Empty!";
}
}
/**
* 将Log保存到本地文件
* @param logMessage 要保存的Log信息
*/
private void saveLogToFile(String logMessage, String logName) {
try {
// 创建日志文件
File logFile = new File(Environment.getExternalStorageDirectory().getPath(), logName+".txt");
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}else {
if(logFile.length() > 5*1024*1024){//大于5M删除
logFile.deleteOnExit();
}
}
FileWriter fileWriter = new FileWriter(logFile, true); // 追加模式
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(logMessage);
bufferedWriter.newLine(); // 换行
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二.AppExecutorUtils
package com.http..utils; import android.os.Handler; import android.os.Looper;import androidx.annotation.NonNull;import java.util.concurrent.Executor; import java.util.concurrent.Executors;/*** **FixedThreadPool**(固定大小线程池):* 适用于任务数固定且相对较小的场景。* 可以控制线程数,避免线程过多导致资源消耗过大。* 适合执行长时间运行的任务。** **CachedThreadPool**(可缓存线程池):* 适用于任务数较多且执行时间较短的场景。* 自动根据任务负载情况调整线程数,可以动态创建和回收线程。* 适合短期的异步任务执行。** **SingleThreadExecutor**(单线程线程池):* 适用于需要保证任务按顺序执行、只有一个线程执行的场景。* 适合串行执行的任务或需要保持任务执行顺序的场景。** **ScheduledThreadPool**(定时任务线程池):* 适用于需要按照计划执行任务的场景,例如定时任务、周期性任务等。* 可以指定任务的执行时间和执行频率。* 根据你的业务需求,你需要考虑以下因素来选择合适的线程池:*/ public class AppExecutorUtils {private final Executor mFixedThreadPool;private final Executor mCachedThreadPool;private final Executor singleThreadExecutor;private final Executor mScheduledThreadPool;private final Executor mMainThread;private AppExecutorUtils(Executor fixedThreadPool, Executor cachedThreadPool, Executor singleThreadExecutor, Executor scheduledThreadPool, Executor mainThread) {this.mFixedThreadPool = fixedThreadPool;this.mCachedThreadPool = cachedThreadPool;this.singleThreadExecutor = singleThreadExecutor;this.mScheduledThreadPool = scheduledThreadPool;this.mMainThread = mainThread;}public AppExecutorUtils() {this(Executors.newFixedThreadPool(10),Executors.newCachedThreadPool(),Executors.newSingleThreadExecutor(),Executors.newScheduledThreadPool(10), new MainThreadExecutor());}public Executor fixedThreadPool() {return mFixedThreadPool;}public Executor cachedThreadPool() {return mCachedThreadPool;}public Executor singleThreadExecutor() {return singleThreadExecutor;}public Executor scheduledThreadPool() {return mScheduledThreadPool;}public Executor mainThread() {return mMainThread;}private static class MainThreadExecutor implements Executor {private Handler mainThreadHandler = new Handler(Looper.getMainLooper());@Overridepublic void execute(@NonNull Runnable command) {mainThreadHandler.post(command);}} }
翻译
搜索
复制