You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin用OkHttp Retrofit拦截器处理超大API响应体问题

OkHttp拦截器压缩带大量表情的响应解决方案

你当前的实现仅对响应长度做了数值减法,既没有读取响应内容完成表情过滤,也没有按照OkHttp规范构造ResponseBody实例,因此无法正常返回。以下是可直接运行的完整实现:


1. 先实现表情过滤工具方法

/**
 * 过滤字符串中的表情
 * @param keepOnlyOne 传true仅保留1个表情,传false移除所有表情
 */
fun String.filterEmoji(keepOnlyOne: Boolean = false): String {
    // 匹配绝大多数表情符号的正则
    val emojiRegex = Regex("\\p{So}")
    return if (keepOnlyOne) {
        val firstEmoji = emojiRegex.find(this)?.value ?: ""
        emojiRegex.replace(this, "") + firstEmoji
    } else {
        emojiRegex.replace(this, "")
    }
}

2. 完整拦截器实现

import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import okio.IOException

class EmojiCompressInterceptor : Interceptor {
    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        val originalResponse = chain.proceed(originalRequest)
        val originalBody = originalResponse.body ?: return originalResponse

        // 替换为你要处理的问题接口路径,避免所有接口都走处理逻辑影响性能
        val targetApiPath = "/your/target/api/path"
        if (!originalRequest.url.encodedPath.contains(targetApiPath)) {
            return originalResponse
        }

        // 仅处理大于500KB的响应,可按需调整阈值
        if (originalBody.contentLength() <= 500 * 1024) {
            return originalResponse
        }

        // 读取原响应内容,注意string()方法只能调用一次,调用后原响应体自动关闭
        val originalContent = originalBody.string()
        // 按需选择是否保留1个表情
        val processedContent = originalContent.filterEmoji(keepOnlyOne = false)

        // 构造新的响应体,保持原有响应的content-type
        val newResponseBody = processedContent.toResponseBody(originalBody.contentType())

        // 返回替换后的新响应
        return originalResponse.newBuilder()
            .body(newResponseBody)
            // 移除旧的Content-Length头,OkHttp会自动计算新的响应长度
            .removeHeader("Content-Length")
            .build()
    }
}

3. 注意事项

  • 如果你要处理的接口返回非UTF-8编码,在调用toResponseBody时需要额外指定编码参数
  • 若现有正则匹配不全你遇到的表情,可以自行扩展正则匹配规则
  • 一定要添加目标接口路径判断,避免所有接口都执行字符串处理逻辑拖慢请求速度

内容的提问来源于stack exchange,提问作者SilverSpoonie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 13:54:07