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

Spring WebSocket:如何拦截@MessageMapping的返回类型

如何拦截Spring WebSocket中返回的NotificationReply对象

嘿,我来帮你搞定这个问题!你已经成功拦截到入站的Notification对象了,要获取控制器返回的NotificationReply其实思路类似,只是需要针对出站消息通道做拦截操作,具体步骤和代码示例如下:

核心思路

你的@SendTo注解指定了返回消息要发送到的topic,这些返回消息最终会通过Spring WebSocket的clientOutboundChannel(客户端出站通道)推送给订阅者,所以我们只需要给这个通道注册拦截器,就能拿到NotificationReply对象。

步骤1:实现出站消息拦截器

同样可以基于ChannelInterceptorAdapter(Spring 5及以上也可以直接实现ChannelInterceptor接口),重写合适的方法来捕获出站消息。这里推荐用preSend方法,它会在消息发送前被调用,能确保你拿到完整的返回对象:

public class OutboundNotificationReplyInterceptor extends ChannelInterceptorAdapter {
    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        // 获取消息的负载内容
        Object payload = message.getPayload();
        // 判断是否是我们要拦截的NotificationReply类型
        if (payload instanceof NotificationReply) {
            NotificationReply reply = (NotificationReply) payload;
            // 这里可以根据业务需求处理这个返回对象,比如打日志、做数据统计等
            System.out.println("成功拦截到返回的NotificationReply: " + reply.toString());
        }
        return super.preSend(message, channel);
    }
}

步骤2:注册拦截器到出站通道

在你的WebSocket配置类中,通过configureClientOutboundChannel方法把刚才写的拦截器注册进去:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    // 这里保留你原有的配置,比如注册端点、配置消息代理等
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/your-websocket-endpoint").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    // 注册出站消息拦截器
    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.interceptors(new OutboundNotificationReplyInterceptor());
    }
}

额外说明

  • 如果你用的是Spring 5.0+,ChannelInterceptorAdapter已经被标记为过时,建议直接实现ChannelInterceptor接口并重写需要的方法。
  • 出站通道可能会有其他类型的消息(比如心跳消息、系统通知等),所以一定要用instanceof判断类型,避免类型转换错误。
  • 如果你想在消息发送完成后做处理,可以重写postSend方法,用法和入站拦截时的逻辑一致。

内容的提问来源于stack exchange,提问作者Manuel Jordan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:38:03