如何捕获Vert.x HttpProxy反向代理收到的响应内容
问题原因
你当前的failureHandler不会被触发的核心原因是:Vert.x Web的failureHandler仅处理路由链执行过程中抛出的异常、或者主动调用RoutingContext.fail()触发的失败逻辑。而反向代理透传后端返回的4xx/5xx属于正常的HTTP响应流程,没有触发路由链的失败逻辑,因此不会进入failureHandler。
实现方案
你可以通过自定义ProxyHandler或者添加代理事件监听器的方式捕获代理收到的响应状态码,两种可行实现方式如下:
方案1:重写ProxyHandler的sendResponse方法(最直接)
直接继承ProxyHandler类,重写负责向后端发送响应的sendResponse方法,在透传响应前先判断状态码,符合自定义处理条件时走自己的逻辑,否则继续走原有的透传逻辑。
// 自定义代理处理器 class CustomProxyHandler extends ProxyHandler { public CustomProxyHandler(HttpProxy proxy) { super(proxy); } @Override protected void sendResponse(RoutingContext context, ProxyResponse proxyResponse) { int statusCode = proxyResponse.statusCode(); // 捕获404状态码做自定义处理 if (statusCode == 404) { context.response() .setStatusCode(404) .putHeader("Content-Type", "text/html;charset=utf-8") .end("<h1>自定义的404页面</h1>"); return; } // 其他状态码走原有透传逻辑 super.sendResponse(context, proxyResponse); } }
修改原来的路由注册代码,把默认的ProxyHandler替换为自定义实现即可:
HttpClient client = theVertx.createHttpClient(); HttpProxy proxy = HttpProxy.reverseProxy(client); Route anyroute = theRouter.route("/*"); // 替换为自定义的CustomProxyHandler anyroute.handler(new CustomProxyHandler(proxy)); anyroute.failureHandler(hnd->{ System.out.println("Failure. Return code: "+hnd.response().getStatusCode()); });
方案2:添加ProxyEvent监听器
如果你不想重写类,也可以给HttpProxy添加事件监听器,在收到后端响应的事件节点做判断处理:
HttpClient client = theVertx.createHttpClient(); HttpProxy proxy = HttpProxy.reverseProxy(client); // 添加代理事件监听器 proxy.addEventHandler(event -> { if (event.type() == ProxyEventType.PROXY_RESPONSE_RECEIVED) { ProxyResponse response = event.proxyResponse(); int status = response.statusCode(); // 这里可以拿到状态码做日志记录等前置处理 if (status == 404) { // 标记事件被处理,终止默认透传逻辑 event.setHandled(true); // 自行返回自定义响应 event.routingContext().response() .setStatusCode(404) .putHeader("Content-Type", "text/html;charset=utf-8") .end("<h1>自定义的404页面</h1>"); } } }); Route anyroute = theRouter.route("/*"); anyroute.handler(ProxyHandler.create(proxy));
注意事项
- 以上方案适用于Vert.x 4.3+版本,低版本的Web Proxy API可能略有差异
- 如果要修改响应内容,注意正确设置Content-Type、Content-Length等响应头,避免浏览器解析异常
- 除了404之外,其他4xx、5xx状态码都可以用同样的逻辑捕获处理
内容的提问来源于stack exchange,提问作者Factor Three
相关产品推荐
相关产品推荐

