refactor(network): 优化网络请求日志记录功能
- 移除Headers导入,添加MultipartBody导入 - 重构logRequest方法,分离日志构建逻辑 - 新增buildRequestLog方法处理请求日志构建 - 新增buildRequestParamsLog方法处理不同请求参数的日志格式化 - 添加GET请求查询参数转换为JSON格式的功能 - 实现multipart表单数据转换为JSON格式的逻辑 - 添加JSON字符串转义功能避免特殊字符问题 - 重构multipartBodyToString方法处理表单字段提取 - 新增mapToJson和escapeJson工具方法
这个提交包含在:
父节点
9e5f68c320
当前提交
3eda1f1305
@ -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<String, String>()
|
||||
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, String>): 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))
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户