Android OkHttp/Retrofit框架使用Interceptor 抓包/mock数据

在Android业务开发中,抓包/mock数据一般有两种方案 (该篇主要介绍第种方案):

一、通过Charles(或fiddle)抓包/mock数据:

二、添加Intercepter来抓取/mock数据:

前提:

网络库使用的是okhttp或Retrofit。

这里就用到了okhttp框架的原理定义一个MockDataInterceptor【Mock数据拦截器】,并在创建Builder实例的时候直接使用addIntercepter【应用拦截器】添加MockDataInterceptor实例即可:

1、addInterceptor(new MockDataInterceptor()):

java 复制代码
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(15, TimeUnit.SECONDS)
       .readTimeout(15, TimeUnit.SECONDS)
       .writeTimeout(15, TimeUnit.SECONDS)
       //在此处添加MockDataInterceptor拦截即可
       .addInterceptor(new MockDataInterceptor())
       .retryOnConnectionFailure(false);

2、MockDataInterceptor定义如下:

java 复制代码
/**
 * Mock数据拦截器
 */
public class MockDataInterceptor implements Interceptor {

    private static final String TAG = "MockDataInterceptor";
    //是否开启mock数据
    private static final boolean mockIsOpen = true;
    private String path;

    private static Map<String, String> pathMap;

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        Headers headers = response.request().headers();
        if (shouldInterceptorRequest(request) && mockIsOpen) {
            //查看Headers请求参数
            Log.d(TAG, "headers:" + headers);

            //查看原始responseBody数据
            Response.Builder builder = response.newBuilder();
            if (response.body() != null) {
                String originalBody = response.body().string();
                Log.d(TAG, "原始的 responseBody:" + originalBody);
            }

            if (!TextUtils.isEmpty(getMockData())) {
                //为responseBody赋值[mock数据]
                ResponseBody responseBody = ResponseBody.create(MediaType.parse("application/json; charset=utf-8"), getMockData());
                builder.body(responseBody);
                Log.d(TAG, "mock数据后 responseBody:" + getMockData());
            }
            return builder.build();
        } else {
            return response;
        }
    }

    //获取对应的mock数据
    private String getMockData() {
        for (String key : pathMap.keySet()) {
            if (path.contains(key)) {
                return pathMap.get(key);
            }
        }
        return "";
    }

    //在此处添加被拦截的接口判断
    private boolean shouldInterceptorRequest(Request request) {
        path = request.url().url().getPath();

        for (String key : pathMap.keySet()) {
            if (path.contains(key)) {
                Log.d(TAG, "path:" + path);
                return true;
            }
        }
        return false;
    }


    public static final String MOCK_DATA_APP_***_*HECK = "{\n" +
            "    \"resMsg\":{\n" +
            "        \"code\":0,\n" +
            "        \"message\":\"\\u6210\\u529f\"\n" +
            "    },\n" +
            "    \"datas\":{\n" +
            "        \"type\":1,\n" +
            "        \"title\":\"\标题",\n" +
            "        \"content\":\"哈哈哈",\n" +
            "        \"url\":\"\"\n" +
            "    }\n" +
            "}";

    //将对应的接口path及该接口mock数据添加到pathMap中
    static {
        pathMap = new HashMap<>();
        pathMap.put("app****heck", MOCK_DATA_APP_***_*HECK);
    }
}

使用前需注意:

  • mock开关是打开的mockIsOpen = true;
  • pathMap中已添加所需的接口path及mock数据。

这样就可以愉快的抓包及mock数据了。

相关推荐
冬奇Lab7 小时前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿9 小时前
Android MediaPlayer 笔记
android
Jony_10 小时前
Android 启动优化方案
android
阿巴斯甜10 小时前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇10 小时前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_14 小时前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android
_小马快跑_14 小时前
Kotlin | 从SparseArray、ArrayMap的set操作符看类型检查的不同
android
_小马快跑_14 小时前
Android | 为什么有了ArrayMap还要再设计SparseArray?
android
_小马快跑_14 小时前
Android TextView图标对齐优化:使用LayerList精准控制drawable位置
android
_小马快跑_14 小时前
Kotlin协程并发控制:多线程环境下的顺序执行
android