From 3eda1f1305654ba7676187235b8a5fa5226eaa00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=8B=A4=E6=B0=91?= Date: Tue, 21 Apr 2026 18:56:57 +0800 Subject: [PATCH] =?UTF-8?q?refactor(network):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E8=AF=B7=E6=B1=82=E6=97=A5=E5=BF=97=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除Headers导入,添加MultipartBody导入 - 重构logRequest方法,分离日志构建逻辑 - 新增buildRequestLog方法处理请求日志构建 - 新增buildRequestParamsLog方法处理不同请求参数的日志格式化 - 添加GET请求查询参数转换为JSON格式的功能 - 实现multipart表单数据转换为JSON格式的逻辑 - 添加JSON字符串转义功能避免特殊字符问题 - 重构multipartBodyToString方法处理表单字段提取 - 新增mapToJson和escapeJson工具方法 --- .../glass/repository/HeaderInterceptor.kt | 83 ++++++++++++++++--- 1 file changed, 73 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt b/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt index d8c6dd8..affa054 100644 --- a/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt +++ b/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt @@ -5,8 +5,8 @@ import com.xuqm.base.common.SHARE_UESR_TOKEN import com.xuqm.base.extensions.getStringForPreferences import com.xuqm.base.extensions.log import com.xuqm.base.extensions.loge -import okhttp3.Headers import okhttp3.Interceptor +import okhttp3.MultipartBody import okhttp3.RequestBody import okhttp3.Response import okio.Buffer @@ -81,21 +81,53 @@ class HeaderInterceptor(val context: Context) : Interceptor { } private fun logRequest(request: okhttp3.Request) { - val requestBodyText = request.body?.let { bodyToString(it) }.orEmpty() - buildString { + buildRequestLog(request).loge() + } + + private fun buildRequestLog(request: okhttp3.Request): String { + return buildString { append("request: ") append(request.method) append(" ") append(request.url) - append('\n') - append("headers: ") - append(request.headers) - if (requestBodyText.isNotBlank()) { + val params = buildRequestParamsLog(request) + if (params.isNotBlank()) { append('\n') append("body: ") - append(requestBodyText) + append(params) } - }.loge() + } + } + + private fun buildRequestParamsLog(request: okhttp3.Request): String { + if (request.method == "GET") { + return urlQueryToJson(request.url) + } + val body = request.body ?: return "" + if (request.method != "POST") { + return bodyToString(body) + } + return when (body) { + is MultipartBody -> multipartBodyToString(body) + else -> bodyToString(body) + } + } + + private fun urlQueryToJson(url: okhttp3.HttpUrl): String { + if (url.querySize == 0) return "" + return buildString { + append("{") + repeat(url.querySize) { index -> + if (index > 0) append(",") + append("\"") + append(escapeJson(url.queryParameterName(index))) + append("\":") + append("\"") + append(escapeJson(url.queryParameterValue(index).orEmpty())) + append("\"") + } + append("}") + } } private fun bodyToString(requestBody: RequestBody): String { @@ -108,7 +140,38 @@ class HeaderInterceptor(val context: Context) : Interceptor { } } - private fun bodyHasUnknownEncoding(headers: Headers): Boolean { + private fun multipartBodyToString(body: MultipartBody): String { + val formFields = linkedMapOf() + body.parts.forEach { part -> + val disposition = part.headers?.get("Content-Disposition").orEmpty() + val name = disposition.substringAfter("name=\"", "").substringBefore('"') + if (name.isBlank()) return@forEach + if ("filename=\"" in disposition) { + return@forEach + } + val value = bodyToString(part.body).trim() + formFields[name] = value + } + return mapToJson(formFields) + } + + private fun mapToJson(fields: Map): String { + if (fields.isEmpty()) return "{}" + return fields.entries.joinToString(prefix = "{", postfix = "}") { + "\"${escapeJson(it.key)}\":\"${escapeJson(it.value)}\"" + } + } + + private fun escapeJson(value: String): String { + return value + .replace("\\", "\\\\") + .replace("\"", "\\\"") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t") + } + + private fun bodyHasUnknownEncoding(headers: okhttp3.Headers): Boolean { val contentEncoding = headers["Content-Encoding"] return (contentEncoding != null && !contentEncoding.equals("identity", ignoreCase = true) && !contentEncoding.equals("gzip", ignoreCase = true))