【实战】OKhttp通过POST提交json数据,打印请求用的拦截器

本文分享了一个用于OkHttp的自定义拦截器实现,能够有效处理POST请求中的JSON数据,并打印请求和响应的详细信息,包括请求头、请求体、响应头及响应体等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:DCTANT

写作背景:网上到处都是用OKhttp配合Retrofit使用Json通过POST提交数据,但是拦截器一个都没有, 坑得要死,还有一篇介绍POST请求用的拦截器的,结果用了发现对json POST数据来说一点用处没有。

为了与时俱进,代码全是用Kotlin写的,毕竟OKhttp4.0也是用Kotlin写的了(觉得不爽来打我啊!O(∩_∩)O哈哈~),主要参考

HttpLoggingInterceptor写的,不然根本写不出来,毕竟RequestBody打断点,能看得见content,就是拿不出来,看得见摸不着,费了我好长时间,最后发现源码中的HTTPLoggingInterceptor用requestBody.writeTo就解决了这个问题,后悔当时没早点看源码。

下面上代码:

import okhttp3.Interceptor
import okhttp3.Response
import okio.Buffer
import java.nio.charset.Charset
import java.util.concurrent.TimeUnit
class PostInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response? {
        val request = chain.request()
        //打印请求起始信息
        val requestStartMsg = "--> ${request.method()} ${request.url()} ${request.body()?.contentLength()}-byte body"
        println(requestStartMsg)
        request.body()?.also { requestBody ->
            val bodyString = "Content-Type: ${requestBody.contentType()} Content-Length: ${requestBody.contentLength()}"
            println(bodyString)
        }
        val requestHeaders = request.headers()
        val size = requestHeaders.size()
        //打印请求头信息
        for (i in 0 until size) {
            val name = requestHeaders.name(i)
            if (!"Content-Type".equals(name, true) && !"Content-Length".equals(name, true)) {
                println("${name} : ${requestHeaders.value(i)}")
            }
        }
        val requestBody = request.body()
        val buffer = Buffer()
        //将请求体内容写入buffer中
        requestBody?.writeTo(buffer)
        println()
        //打印整个请求体中的内容(这步全靠打断点找出来的)
        println(buffer.readByteString().utf8())
        println("--> END ${request.method()} (${requestBody?.contentLength()}-byte body)")

        val startNs = System.nanoTime()
        //执行请求
        val response = chain.proceed(request)
        //计算耗时
        val tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs)
        requestBody?.also { requestBody ->
            //请求完成后打印请求信息
            val bodyInfo = "<-- ${response.code()} ${response.message()} ${response.request().url()} (${tookMs} ms) Content-Length ${requestBody.contentLength()}"
            println(bodyInfo)
        } ?: also {
            println("No request body found!!")
        }
        val responseHeaders = response.headers()
        //打印Response头中的信息
        for (i in 0 until requestHeaders.size()) {
            println("${responseHeaders.name(i)} : ${responseHeaders.value(i)}")
        }
        response.body()?.also { responseBody ->
            val source = responseBody.source()
            source.request(Long.MAX_VALUE)
            val sourceBuffer = source.buffer()
            //打印Response中的内容(如果直接用responseBody.string()会导致流关闭而报错!java.lang.IllegalStateException: closed)
            println(sourceBuffer.clone().readString(Charset.defaultCharset()))
            println("<-- END HTTP (${sourceBuffer.size()} -byte body)")
        } ?: also {
            println("<-- END HTTP No response body found!")
        }
        return response
    }
}

使用:OKhttpClient.Builder()的时候addInterceptor中new 一个PostInterceptor即可

使用效果:

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值