Spring WebSockets - 如何将@DestinationVariable 仅应用于@SendTo 注释?
Spring WebSockets - how to apply @DestinationVariable only to @SendTo annotation?
我正在尝试将目标变量应用于我的控制器中处理来自 WebSocket 的传入消息的方法。这是我想要实现的目标:
@Controller
public class DocumentWebsocketController {
@MessageMapping("/lock-document")
@SendTo("/notify-open-documents/{id}")
public Response response(@DestinationVariable("id") Long id, Message message) {
return new Response(message.getDocumentId());
}
}
问题是,目标变量仅应用于 @SendTo
注释。尝试此端点时会导致以下堆栈跟踪:
12:36:43.044 [clientInboundChannel-7] ERROR org.springframework.web.socket.messaging.WebSocketAnnotationMethodMessageHandler - Unhandled exception
org.springframework.messaging.MessageHandlingException: Missing path template variable 'id' for method parameter type [class java.lang.Long]
at org.springframework.messaging.handler.annotation.support.DestinationVariableMethodArgumentResolver.handleMissingValue(DestinationVariableMethodArgumentResolver.java:70) ~[spring-messaging-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.messaging.handler.annotation.support.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:96) ~[spring-messaging-4.2.4.RELEASE.jar:4.2.4.RELEASE]
(...)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_144]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_144]
我的问题是:我想要实现的东西有可能实现吗?
这应该是可以的。我指的是以下答案:Path variables in Spring WebSockets @SendTo mapping
Update: In Spring 4.2, destination variable placeholders are supported it's now possible to do something like:
@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
@SendTo("/topic/fleet/{fleetId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
return new Simple(fleetId, driverId);
}
您得到的错误是告诉您在您的目的地(在您的 @MessageMapping
中定义)中没有名为 id
的占位符。 @DestinationVariable
尝试从传入目的地获取变量,它并不像您尝试的那样绑定到传出目的地。但是,您可以在 @SendTo
中的 @MessageMapping
中使用相同的占位符(但这不是您的情况)。
如果您想拥有一个动态目的地,请使用 MessagingTemplate
,例如:
@MessageMapping("/lock-document")
public void response(Message message) {
simpMessagingTemplate.convertAndSend("/notify-open-documents/" + message.getDocumentId(), new Response(message.getDocumentId());
}
我正在尝试将目标变量应用于我的控制器中处理来自 WebSocket 的传入消息的方法。这是我想要实现的目标:
@Controller
public class DocumentWebsocketController {
@MessageMapping("/lock-document")
@SendTo("/notify-open-documents/{id}")
public Response response(@DestinationVariable("id") Long id, Message message) {
return new Response(message.getDocumentId());
}
}
问题是,目标变量仅应用于 @SendTo
注释。尝试此端点时会导致以下堆栈跟踪:
12:36:43.044 [clientInboundChannel-7] ERROR org.springframework.web.socket.messaging.WebSocketAnnotationMethodMessageHandler - Unhandled exception
org.springframework.messaging.MessageHandlingException: Missing path template variable 'id' for method parameter type [class java.lang.Long]
at org.springframework.messaging.handler.annotation.support.DestinationVariableMethodArgumentResolver.handleMissingValue(DestinationVariableMethodArgumentResolver.java:70) ~[spring-messaging-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.messaging.handler.annotation.support.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:96) ~[spring-messaging-4.2.4.RELEASE.jar:4.2.4.RELEASE]
(...)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_144]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_144]
我的问题是:我想要实现的东西有可能实现吗?
这应该是可以的。我指的是以下答案:Path variables in Spring WebSockets @SendTo mapping
Update: In Spring 4.2, destination variable placeholders are supported it's now possible to do something like:
@MessageMapping("/fleet/{fleetId}/driver/{driverId}")
@SendTo("/topic/fleet/{fleetId}")
public Simple simple(@DestinationVariable String fleetId, @DestinationVariable String driverId) {
return new Simple(fleetId, driverId);
}
您得到的错误是告诉您在您的目的地(在您的 @MessageMapping
中定义)中没有名为 id
的占位符。 @DestinationVariable
尝试从传入目的地获取变量,它并不像您尝试的那样绑定到传出目的地。但是,您可以在 @SendTo
中的 @MessageMapping
中使用相同的占位符(但这不是您的情况)。
如果您想拥有一个动态目的地,请使用 MessagingTemplate
,例如:
@MessageMapping("/lock-document")
public void response(Message message) {
simpMessagingTemplate.convertAndSend("/notify-open-documents/" + message.getDocumentId(), new Response(message.getDocumentId());
}