美文网首页
基于 OkHttp 的日志拦截器

基于 OkHttp 的日志拦截器

作者: 雁过留声_泪落无痕 | 来源:发表于2021-03-10 13:59 被阅读0次
package com.xxx;

import android.text.TextUtils;

import com.blankj.utilcode.util.JsonUtils;
import com.blankj.utilcode.util.LogUtils;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.GzipSource;

/**
 * 官方提供的 {@link okhttp3.logging.HttpLoggingInterceptor} 不能将一个完整的请求日志包在一起,
 * 当有多个请求同时进行的时候,容易串行。
 * <p>
 * 使用该类,结合 {@link com.blankj.utilcode.util.LogUtils} 可将一个完成的请求日志在一起打印出来。
 * <p>
 * 未打印 HEADERS。
 * <p>
 * 示例:
 * ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 * │ OkHttp http://xxx/..., com.xxx.MyHttpLogInterceptor.intercept(MyHttpLogInterceptor.java:109)
 * ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
 * │ --> POST http://xxx/getXXX
 * │ {
 * │  "data": null,
 * │  "code": 200,
 * │  "message": "提交成功"
 * │ }
 * │ <-- 200
 * └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 */
public class MyHttpLogInterceptor implements Interceptor {

    private static final String OK_HTTP_TAG = "OkHttp";

    private boolean mEnableBody;

    public MyHttpLogInterceptor() {
        this(false);
    }

    public MyHttpLogInterceptor(boolean enableBody) {
        this.mEnableBody = enableBody;
    }

    @NotNull
    @Override
    public Response intercept(@NotNull Chain chain) throws IOException {
        Request request = chain.request();

        // 打印请求方法和 url 地址
        StringBuilder sb = new StringBuilder("--> ");
        sb.append(request.method()).append(" ").append(request.url().toString());

        // 打印 RequestBody
        RequestBody requestBody = request.body();
        if (requestBody != null) {
            Buffer buffer = new Buffer();
            requestBody.writeTo(buffer);
            String requestBodyStr = buffer.readString(StandardCharsets.UTF_8);
            if (!TextUtils.isEmpty(requestBodyStr)) {
                sb.append(" ").append(requestBodyStr);
            }
        }
        sb.append("\n");

        Response response;
        try {
            response = chain.proceed(request);
        } catch (Exception e) {
            sb.append("<-- HTTP FAILED: ").append(e.toString());
            LogUtils.dTag(OK_HTTP_TAG, sb.toString());
            throw e;
        }

        // 打印 ResponseBody
        if (mEnableBody) {
            ResponseBody responseBody = response.body();
            if (null != responseBody) {
                Headers headers = response.headers();
                BufferedSource source = responseBody.source();
                // Buffer the entire body.
                source.request(Long.MAX_VALUE);
                Buffer buffer = source.getBuffer();

                if ("gzip".equalsIgnoreCase(headers.get("Content-Encoding"))) {
                    GzipSource gzipSource = new GzipSource(buffer.clone());
                    buffer = new Buffer();
                    buffer.writeAll(gzipSource);
                    gzipSource.close();
                }

                String body = buffer.clone().readString(StandardCharsets.UTF_8);
                if (!TextUtils.isEmpty(body)) {
                    String formatted = JsonUtils.formatJson(body, 1);
                    if (formatted.length() < 700) {
                        sb.append(formatted);
                    } else {
                        sb.append(body);
                    }
                } else {
                    sb.append("no body.");
                }
                sb.append("\n");
            }
        }

        // 打印响应码
        sb.append("<-- ").append(response.code()).append(" ").append(response.message());
        LogUtils.dTag(OK_HTTP_TAG, sb.toString());

        return response;
    }

}

相关文章

网友评论

      本文标题:基于 OkHttp 的日志拦截器

      本文链接:https://www.haomeiwen.com/subject/wlswqltx.html