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
相关产品推荐
相关产品推荐

