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拦截器来拦截端点的消息处理方法:
- 定义拦截器绑定注解:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @InterceptorBinding public @interface WsMessageIntercept {}
- 实现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(); } }
- 在客户端端点的消息方法上添加注解:
@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
相关产品推荐
相关产品推荐

