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

Quarkus中如何读取请求体并保证vertx-http-proxy正常运行?

Quarkus中vert.x-http-proxy读取请求体异常的解决方法

vert.x-http-proxy内部会自行管理请求体的流转逻辑,直接在拦截器中消费请求体或使用BodyHandler都会导致请求体被提前耗尽,引发代理卡住或“已读取”异常。以下是具体解决思路和代码实现:

核心问题原因

  • vert.x-http-proxy依赖原始请求体的流完成代理转发,若请求体被提前读取(比如通过BodyHandler或同步读取API),后续代理流程将无法获取有效请求体,导致异常。
  • 拦截器中必须通过异步API读取请求体,且读取完成后需将请求体重新写回请求对象,保证代理流程能继续使用。

解决方案代码

自定义拦截器实现

val myInterceptor = object : ProxyInterceptor {
    override fun handleRequest(proxyContext: ProxyContext): Future<Void> {
        val request = proxyContext.request()
        
        // 异步读取请求体
        return request.body()
            .compose { buffer ->
                // 在这里处理请求体,比如校验内容、解析参数
                val bodyContent = buffer.toString(Charsets.UTF_8)
                // 示例:打印请求体内容
                println("请求体内容: $bodyContent")

                // 关键步骤:将读取后的请求体重新设置回请求,确保代理能继续转发
                request.setBody(buffer)
                Future.succeededFuture()
            }
            .onFailure { error ->
                // 处理请求体读取失败的场景
                proxyContext.response()
                    .setStatusCode(HttpResponseStatus.BAD_REQUEST.code())
                    .end("请求体读取失败: ${error.message}")
            }
    }

    // 响应拦截可根据需求实现,此处默认返回成功
    override fun handleResponse(proxyContext: ProxyContext): Future<Void> {
        return Future.succeededFuture()
    }
}

代理初始化代码(调整后)

fun onStart(@Observes router: Router, vertx: Vertx) {
    val proxyClient: HttpClient = vertx.createHttpClient(
        HttpClientOptions().setTrustAll(false)
    )

    val proxy: HttpProxy = HttpProxy.reverseProxy(proxyClient)
        .origin(8888, "localhost")
        .addInterceptor(myInterceptor)

    router
        .route()
        .path("/authorized/*")
        .handler(ProxyHandler.create(proxy))
}

注意事项

  • 全程使用vert.x的异步API(Future、compose)处理请求体,避免阻塞线程影响Quarkus的非阻塞性能。
  • 若请求体是JSON格式,可使用vert.x的Json.decodeValue(buffer, YourDto::class.java)进行解析,无需手动转字符串。
  • 处理大请求体时,建议使用流式读取(request.bodyStream()),避免一次性加载到内存,同时需确保流的正确传递,防止代理流程中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 18:05:23