|
对于最新稳定版本,请使用Spring Framework 7.0.1! |
注释控制器
应用程序可以使用带注释的@Controller处理客户端消息的类。
此类类可以声明@MessageMapping,@SubscribeMapping和@ExceptionHandler方法,如下主题所述:
@MessageMapping
你可以使用@MessageMapping用于注释基于
目的地。它不仅在方法层面得到支持,也在类型层面得到支持。在类型
水平@MessageMapping用于表达在 a 中所有方法之间的共享映射
控制器。
默认情况下,映射值为Ant风格路径模式(例如)/东西*,/东西/**),
包括对模板变量的支持(例如,/thing/{id}).这些值可以是
参考文献@DestinationVariable方法论元。应用程序也可以切换到
一种点分的目标约定,详见《点作为分隔符》一书。
支持的方法参数
下表描述了方法参数:
| 方法论证 | 描述 |
|---|---|
|
获取完整信息。 |
|
为了访问 |
|
通过类型访问访问器方法访问头部。 |
|
访问消息的有效载荷,通过配置转换(例如从JSON)进行转换 不需要该注释的存在,因为默认假设没有则默认存在 另一种论点也相符。 你可以用 来注释载荷参数 |
|
为了访问特定的头部值——以及使用以下方式进行类型转换 |
|
访问消息中所有头部。该参数必须可分配于 |
|
访问从消息目的地提取的模板变量。 值会根据需要转换为声明的方法参数类型。 |
|
显示用户在WebSocket HTTP握手时登录。 |
回报值
默认情况下,来自@MessageMapping方法被序列化为有效载荷
通过匹配消息转换器并被派往消息前往brokerChannel,
节目从那里向订户播出。外发消息的目的地是
与入站消息相同,但前缀为/主题.
你可以使用@SendTo和@SendToUser用于自定义目标的注释
输出消息。@SendTo用于自定义目标目的地或
指定多个目的地。@SendToUser用于引导输出消息
仅对与输入消息相关的用户。参见用户目的地。
你可以两者兼用@SendTo和@SendToUser同时用同一方法,且两者都做
在类级层面支持,在这种情况下,它们作为
类。不过,请记住,任何方法层面@SendTo或@SendToUser附注
在类级层面覆盖所有此类注释。
消息可以异步处理,并且@MessageMapping方法可以返回可听未来,完成未来或完成阶段.
注意@SendTo和@SendToUser仅仅是方便,实际上就是使用SimpMessageaging模板传递信息。如有必要,在更高级的场景中,@MessageMapping方法可以退回使用SimpMessageaging模板径直。
这可以代替,也可以作为返回值的补充方式进行。
参见发送消息。
@SubscribeMapping
@SubscribeMapping类似于@MessageMapping但会将映射范围缩小到
仅限订阅消息。它支持的方法参数与@MessageMapping.然而
对于返回值,默认情况下,消息直接发送给客户端(通过clientOutboundChannel,响应订阅)而非经纪人(通过brokerChannel,作为对匹配订阅的广播)。添加@SendTo或@SendToUser会覆盖这种行为,转而发送给经纪人。
这在什么时候有用?假设经纪人映射到/主题和/队列而
应用控制器映射到/应用程序.在此设置中,经纪人会存储所有
订阅/主题和/队列用于重复广播,
申请人无需介入。客户端也可以订阅
一些/应用程序目的地,控制器可以返回相应的值
无需经纪人参与即可订阅,无需再次存储或使用订阅
(实际上是一次性的请求-回复交换)。其中一个用例是填充用户界面
初始数据为启动。
什么时候这才不实用?不要尝试将代理和控制器映射到同一个目的地 除非你希望两者独立处理消息,包括订阅, 不知为何。入站消息是并行处理的。没有保证 经纪人或控制器首先处理给定消息。如果目标是被通知 当订阅存储完成并准备广播时,客户端应要求 如果服务器支持,则是收据(Simple Broker不支持)。例如,使用 Java STOMP 客户端,你可以这样做添加收据:
@Autowired
private TaskScheduler messageBrokerTaskScheduler;
// During initialization..
stompClient.setTaskScheduler(this.messageBrokerTaskScheduler);
// When subscribing..
StompHeaders headers = new StompHeaders();
headers.setDestination("/topic/...");
headers.setReceipt("r1");
FrameHandler handler = ...;
stompSession.subscribe(headers, handler).addReceiptTask(receiptHeaders -> {
// Subscription ready...
});
服务器端的一种选择是注册一个执行者通道拦截者在brokerChannel并实现消息处理后在处理完消息(包括订阅)后调用的方法。
@MessageExceptionHandler
应用程序可以使用@MessageExceptionHandler处理异常的方法来自@MessageMapping方法。你可以在注释中声明例外
无论是自己,还是通过方法参数访问异常实例。
以下示例通过方法参数声明异常:
@Controller
public class MyController {
// ...
@MessageExceptionHandler
public ApplicationError handleException(MyException exception) {
// ...
return appError;
}
}
@MessageExceptionHandler方法支持灵活的方法签名和支持
与方法参数类型和返回值相同@MessageMapping方法。
通常@MessageExceptionHandler方法适用于@Controller类
(或类别等级),其中他们被宣布。如果你想应用这些方法
更全局地(跨控制器),你可以在一个标记为@ControllerAdvice.这与春季MVC中类似的支持相当。