好用的自定义Okhttp日志拦截器

Okhttp中自带的日志拦截器 HttpLoggingInterceptor 实在是不好用,日志太多太乱,所以想要有好看、简洁的日志打印就要靠自定义了,下面分享我参照 HttpLoggingInterceptor 写的自定义日志打印拦截器,分为java版本和kotlin版本:

1、kotlin:

class CustomLogInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val requestLog = generateRequestLog(request)
        val response = chain.proceed(request)
        val responseLog = generateResponseLog(response)
        LogUtils.w(requestLog.plus(responseLog))
        return response
    }

    private fun generateResponseLog(response: Response?): String {
        if (response == null) {
            return ""
        }
        return "Response Time-->:${
            TimeUtils.millis2String(System.currentTimeMillis())
        } \r\n Response Result ${
            if (response.code != 200)
                response.code
            else
                ""
        } -->:${
            getResponseText(response)
        }"
    }

    private fun generateRequestLog(request: Request?): String {
        if (request == null) {
            return ""
        }
        val requestParams = getRequestParams(request)
        val needPrintRequestParams = requestParams.contains("IsFile").not()
        return "自定义日志打印 \r\n Request Time-->:${
            TimeUtils.millis2String(System.currentTimeMillis())
        } \r\n Request Url-->:${request.method} ${request.url} \r\n Request Header-->:${
            getRequestHeaders(
                    request
            )
        } \r\n Request Parameters-->:${
            if (needPrintRequestParams)
                requestParams
            else
                "文件上传,不打印请求参数"
        } \r\n "
    }

    @Deprecated("unused")
    private fun printInfo(request: Request?, response: Response?) {
        if (request != null && response != null) {
            val requestParams = getRequestParams(request)
            val needPrintRequestParams = requestParams.contains("IsFile").not()
            val logInfo =
                    "自定义日志打印 \r\n Request Url-->:${request.method} ${request.url} \r\n Request Header-->:${
                        getRequestHeaders(
                                request
                        )
                    } \r\n Request Parameters-->:${
                        if (needPrintRequestParams)
                            requestParams
                        else
                            "文件上传,不打印请求参数"
                    } \r\n Response Result ${
                        if (response.code != 200)
                            response.code
                        else
                            ""
                    } -->:${
                        getResponseText(response)
                    }"
            LogUtils.w(logInfo)
        }
    }

    /**
     * 获取请求参数
     */
    private fun getRequestParams(request: Request): String {
        var str: String? = null
        try {
            request.body?.let {
                val buffer = Buffer()
                it.writeTo(buffer)
                val charset = it.contentType()?.charset(Charset.forName("UTF-8"))
                        ?: Charset.forName("UTF-8")
                str = buffer.readString(charset)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return if (str.isNullOrEmpty()) "Empty!" else str!!
    }

    private fun getRequestHeaders(request: Request): String {
        val headers = request.headers
        return if (headers.size > 0) {
            headers.toString()
        } else {
            "Empty!"
        }
    }

    /**
     * 获取返回数据字符串
     */
    private fun getResponseText(response: Response): String {
        try {
            response.body?.let {
                val source = it.source()
                source.request(Long.MAX_VALUE)
                val buffer = source.buffer
                val charset = it.contentType()?.charset(Charset.forName("UTF-8"))
                        ?: Charset.forName("UTF-8")
                if (it.contentLength().toInt() != 0) {
                    buffer.clone().readString(charset).let { result ->
                        return result
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return "Empty!"
    }
}

2、Java:

public class CustomLogInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        printInfo(request, response);
        return response;
    }

    private void printInfo(Request request, Response response) {
        if (request != null && response != null) {
            String logInfo = "自定义日志打印".concat(" \r\n ")
                    .concat("Request Url-->:")
                    .concat(request.method())
                    .concat(" ")
                    .concat(request.url().toString())
                    .concat(" \r\n ")
                    .concat("Request Header-->:")
                    .concat(getRequestHeaders(request))
                    .concat(" \r\n ")
                    .concat("Request Parameters-->:")
                    .concat(getRequestParams(request))
                    .concat(" \r\n ")
                    .concat("Response Result-->:")
                    .concat(getResponseText(response));
            Logger.w(logInfo);
        }
    }

    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);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }

    private String getRequestHeaders(Request request) {
        Headers headers = request.headers();
        if (headers.size() > 0) {
            return headers.toString();
        } else {
            return "Empty!";
        }
    }
}

其中使用到的第三方SDK为:
日志打印:AndroidUtilCode
网络请求:OkHttp

打印效果:
好用的自定义Okhttp日志拦截器
Kotlin版本仅仅比Java版本多了两行时间的打印,从而可以计算当前请求的 大概 耗时,如果需要精确的耗时请使用 OkHttpClient.Builder().eventListener(eventListener: EventListener)

上一篇:[改善Java代码]覆写equals方法时不要识别不出自己


下一篇:android okhttp 响应