package com.example.smart.reqeust.interceptor import android.annotation.SuppressLint import android.util.Log import okhttp3.Interceptor import okhttp3.MediaType import okhttp3.MultipartBody import okhttp3.Request import okhttp3.Response import okhttp3.ResponseBody import okio.Buffer import retrofit2.Invocation import retrofit2.http.Streaming import java.io.IOException import java.net.URLDecoder import java.nio.charset.StandardCharsets class LoggingInterceptorZmc : Interceptor { @SuppressLint("LogNotTimber") @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { val request: Request = chain.request() val startTime = System.currentTimeMillis() Log.d(TAG + "-" + Thread.currentThread().id, "----------Start----------------") if ("GET".equals(request.method, ignoreCase = true) || "DELETE".equals( request.method, ignoreCase = true ) ) { Log.d( TAG + "-" + Thread.currentThread().id, "| " + URLDecoder.decode(request.toString(), StandardCharsets.UTF_8.name()) ) } else { val requestInfo = "Request{method=" + request.method + ", url=" + request.url + ", head=" + request.headers + "}" Log.d(TAG + "-" + Thread.currentThread().id, "| $requestInfo") try { val jsonInfo = "RequestParams:" + URLDecoder.decode( bodyToString(request), StandardCharsets.UTF_8.name() ) Log.d(TAG + "-" + Thread.currentThread().id, "| $jsonInfo") } catch (e: Exception) { Log.e( TAG + "-" + Thread.currentThread().id, "| " + "RequestParams:" + bodyToString(request) ) Log.e(TAG + "-" + Thread.currentThread().id, "| " + "error:" + e.message) } } val response: Response = chain.proceed(request) val endTime = System.currentTimeMillis() val duration = endTime - startTime if (!request.containMethodAnnotation(Streaming::class.java)) { val bodyString = response.body!!.string() Log.d(TAG + "-" + Thread.currentThread().id, "| Response:$bodyString") Log.d( TAG + "-" + Thread.currentThread().id, "----------End:" + duration + "毫秒----------" ) val newBody = ResponseBody.create(response.body!!.contentType(), bodyString) return response.newBuilder() .body(newBody) .build() } else { Log.d(TAG + "-" + Thread.currentThread().id, "| Response:{数据流}") Log.d( TAG + "-" + Thread.currentThread().id, "----------End:" + duration + "毫秒----------" ) return response.newBuilder() .body(response.body!!) .build() } } private fun bodyToString(request: Request): String { try { val copy = request.newBuilder().build() val buffer = Buffer() if (copy.body is MultipartBody) { val multipartBody = copy.body as MultipartBody? for (i in 0 until multipartBody!!.size) { val part = multipartBody.part(i) val mediaType = part.body.contentType() if (!isFilePart(mediaType)) { part.body.writeTo(buffer) } else { buffer.writeUtf8("file params Content-Type: $mediaType\n") } } } else { copy.body!!.writeTo(buffer) } return buffer.readUtf8() } catch (e: IOException) { return "did not work" } } // 是否为文件 fun isFilePart(mediaType: MediaType?): Boolean { if (mediaType != null) { val type = mediaType.toString() return type.startsWith("audio/") || type.startsWith("text/plain") || type.startsWith("multipart/form-data") } return false } /** * 返回某个Retrofit定义在方法上的注解,例如[POST],[GET] */ fun Request.getMethodAnnotation(annotationClass: Class): T? { return tag(Invocation::class.java)?.method()?.getAnnotation(annotationClass) } fun Request.containMethodAnnotation(annotationClass: Class): Boolean { return getMethodAnnotation(annotationClass) != null } companion object { private const val TAG = "zmc-Log" } }