点作为分隔符
当消息路由到 @MessageMapping 方法时,它们使用 AntPathMatcher 进行匹配。默认情况下,模式(Patterns)预期使用斜杠 (/) 作为分隔符。这在 Web 应用程序中是一个很好的惯例,且与 HTTP URL 相似。然而,如果你更习惯消息传递中间件的惯例,可以切换为使用点 (.) 作为分隔符。
配置分隔符
以下示例显示了如何进行配置:
java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 切换路径匹配器为使用点号分隔
registry.setPathMatcher(new AntPathMatcher("."));
registry.enableStompBrokerRelay("/queue", "/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}kotlin
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
override fun configureMessageBroker(registry: MessageBrokerRegistry) {
registry.setPathMatcher(AntPathMatcher("."))
registry.enableStompBrokerRelay("/queue", "/topic")
registry.setApplicationDestinationPrefixes("/app")
}
}xml
<websocket:message-broker application-destination-prefix="/app" path-matcher="pathMatcher">
<websocket:stomp-endpoint path="/stomp"/>
<websocket:stomp-broker-relay prefix="/topic,/queue" />
</websocket:message-broker>
<bean id="pathMatcher" class="org.springframework.util.AntPathMatcher">
<constructor-arg index="0" value="."/>
</bean>控制器用法
之后,控制器可以在 @MessageMapping 方法中使用点 (.) 作为分隔符:
java
@Controller
@MessageMapping("red")
public class RedController {
@MessageMapping("blue.{green}")
public void handleGreen(@DestinationVariable String green) {
// 逻辑处理
}
}kotlin
@Controller
@MessageMapping("red")
class RedController {
@MessageMapping("blue.{green}")
fun handleGreen(@DestinationVariable green: String) {
// 逻辑处理
}
}现在客户端可以向 /app/red.blue.green123 发送消息。
补充教学
1. 为什么要用点号?
在传统的 MQ 环境(如 RabbitMQ 或 MQTT)中,点号通常被用作 Topic 的层级分隔符(例如 sensor.livingroom.temperature)。如果你的前端或物联网设备已经遵循这种命名规范,在 Spring 中开启点号支持可以保持命名风格的一致性。
2. 只有内置代理受此影响
上述配置主要影响 Spring 的 Annotated Controllers 路由和内置的“简单代理”。如果你使用的是“外部代理中继”(Broker Relay),转发给 RabbitMQ 的前缀(如 /topic)规则仍取决于外部代理自身的配置,Spring 不会强制修改它们。
3. 注意混淆
路径中的第一个片段(如 /app 或 /topic)通常仍建议保留前导斜杠,以符合标准的 URL 路由直觉,只有在那之后的子路径才使用点号。