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

Quarkus中无法用@WebFilter拦截WebSocket客户端请求问题

解决Quarkus中WebSocket客户端请求无法被@WebFilter拦截的问题

首先明确:Quarkus里的@WebFilter仅作用于Servlet/REST请求的处理链,WebSocket请求不走Servlet容器的处理流程,所以用它拦截WebSocket客户端请求是无效的,这和Thorntail的实现逻辑不同。下面给出几种可行的替代方案:

方案1:使用标准JSR-356客户端拦截器拦截握手请求

实现ClientEndpointInterceptor接口,通过它拦截WebSocket客户端的握手请求和响应:

public class WebSocketClientInterceptor implements ClientEndpointInterceptor {
    @Override
    public boolean beforeRequest(HandshakeRequest request) {
        // 前置拦截逻辑:修改请求头、记录日志等
        request.getHeaders().put("X-Client-ID", Collections.singletonList("quarkus-migrated"));
        return true; // 返回true继续握手,false终止
    }

    @Override
    public void afterResponse(HandshakeResponse response) {
        // 响应后处理:校验响应头、记录状态等
        System.out.println("WebSocket握手响应状态:" + response.getStatus());
    }
}

然后在客户端端点类上指定该拦截器:

@ClientEndpoint(interceptors = WebSocketClientInterceptor.class)
public class MyWsClient {
    @OnOpen
    public void onOpen(Session session) {
        // 连接打开后的逻辑
    }

    @OnMessage
    public void onMessage(String msg) {
        // 消息处理逻辑
    }
}

方案2:编程式配置客户端时添加握手拦截

如果是通过代码手动创建WebSocket客户端,可以直接通过ClientEndpointConfig.Configurator来拦截握手请求:

ClientEndpointConfig clientConfig = ClientEndpointConfig.Builder.create()
        .configurator(new ClientEndpointConfig.Configurator() {
            @Override
            public void beforeRequest(Map<String, List<String>> headers) {
                // 在这里修改或添加请求头,实现拦截逻辑
                headers.put("X-Custom-Header", Collections.singletonList("intercepted"));
            }
        })
        .build();

// 连接到服务端
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(MyWsClient.class, clientConfig, new URI("ws://your-server/ws-path"));

方案3:拦截WebSocket消息(非握手阶段)

如果需要拦截的是WebSocket的消息收发,而非握手请求,可以用CDI拦截器来拦截端点的消息处理方法:

  1. 定义拦截器绑定注解:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@InterceptorBinding
public @interface WsMessageIntercept {}
  1. 实现CDI拦截器:
@Interceptor
@WsMessageIntercept
public class WsMessageInterceptor {
    @AroundInvoke
    public Object interceptMessage(InvocationContext ctx) throws Exception {
        // 拦截消息:比如记录消息内容、校验格式等
        Object[] params = ctx.getParameters();
        if (params.length > 0) {
            System.out.println("拦截到WebSocket消息:" + params[0]);
        }
        return ctx.proceed();
    }
}
  1. 在客户端端点的消息方法上添加注解:
@ClientEndpoint
public class MyWsClient {
    @OnMessage
    @WsMessageIntercept
    public void handleMessage(String message) {
        // 原消息处理逻辑
    }
}

注意事项

确保项目中已经引入Quarkus WebSocket扩展,在pom.xml中添加:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-websockets</artifactId>
</dependency>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 11:20:28