当前位置: 首页 > news >正文

拦截指定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);}}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 左神学习笔记-岛屿数量问题(java版算法)
  • 堆排序以及向上、向下调整算法的时间复杂度推导及实现(超详细)
  • 五种创建springBoot项目的方法(本质上是三种)
  • FFmpeg学习
  • C语言从头学44——I/O 函数(一)
  • 软件测试生命周期、BUG描述与处理策略
  • leetcode面试算法题
  • Java程序员接单分享
  • Redis远程字典服务器(1)—— 初识Redis
  • SSH协议管理多主机(SSH协议的两种用法、生产环境用户初始化、结果返回值处理)
  • 人工智能算法工程师(高级)课程11-自然语言处理之NLP的语言模型-seq2seq模型,seq+注意力与代码详解
  • 【数据结构】链表篇
  • 深入解析:Amazon Bedrock 上 Claude 3 Haiku 的微调测试报告
  • 基于STM32的智能宠物喂食器
  • MySQL的索引事务和JDBC编程
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • ES6之路之模块详解
  • js 实现textarea输入字数提示
  • Logstash 参考指南(目录)
  • Mybatis初体验
  • Mysql数据库的条件查询语句
  • node 版本过低
  • scrapy学习之路4(itemloder的使用)
  • unity如何实现一个固定宽度的orthagraphic相机
  • 程序员该如何有效的找工作?
  • 复杂数据处理
  • 搞机器学习要哪些技能
  • 浏览器缓存机制分析
  • 排序算法之--选择排序
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 思考 CSS 架构
  • mysql面试题分组并合并列
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • # .NET Framework中使用命名管道进行进程间通信
  • #if #elif #endif
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • #stm32整理(一)flash读写
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (ISPRS,2021)具有遥感知识图谱的鲁棒深度对齐网络用于零样本和广义零样本遥感图像场景分类
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (七)Flink Watermark
  • (四)js前端开发中设计模式之工厂方法模式
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (转)详解PHP处理密码的几种方式
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献