我與彈簧的WebSocket工作,我有以下問題:@MessageMapping用佔位符
我試圖把一個佔位符@MessageMapping
註釋裏面,以獲得從屬性的URL。它適用於@RequestMapping
,但不適用於@MessageMapping
。
如果我使用此佔位符,則URL爲空。任何想法或建議?
例子:
@RequestMapping(value= "${myProperty}")
@MessageMapping("${myProperty}")
我與彈簧的WebSocket工作,我有以下問題:@MessageMapping用佔位符
我試圖把一個佔位符@MessageMapping
註釋裏面,以獲得從屬性的URL。它適用於@RequestMapping
,但不適用於@MessageMapping
。
如果我使用此佔位符,則URL爲空。任何想法或建議?
例子:
@RequestMapping(value= "${myProperty}")
@MessageMapping("${myProperty}")
Rossen Stoyanchev爲@MessageMapping和@SubscribeMapping方法添加了佔位符支持。
更新:
現在我明白你的意思,但我認爲這是不可能的(還)。
Documentation沒有提及與路徑映射URI相關的任何內容。
老答案
使用
@MessageMapping("/handler/{myProperty}")
,而不是
@MessageMapping("/handler/${myProperty}")
而且使用這樣的:
@MessageMapping("/myHandler/{username}")
public void handleTextMessage(@DestinationVariable String username,Message message) {
//do something
}
Spring允許您在@RequestMapping
中使用屬性佔位符,但不允許在@MessageMapping
中使用屬性佔位符。這是'因爲MessageHandler
。所以,我們需要覆蓋默認MessageHandler
來做到這一點。
不支持佔位符,您需要自己添加此支持。
爲了簡單起見,我剛剛創建在我的項目另一WebSocketAnnotationMethodMessageHandler
類在同一個包,原來,org.springframework.web.socket.messaging
,並從SimpAnnotationMethodMessageHandler
覆蓋getMappingForMethod
方法有相同的內容,只能用這個這個方法(private
在WebSocketAnnotationMethodMessageHandler
如何SimpMessageMappingInfo
池莉構建變化):現在
private SimpMessageMappingInfo createMessageMappingCondition(final MessageMapping annotation) {
return new SimpMessageMappingInfo(SimpMessageTypeMessageCondition.MESSAGE, new DestinationPatternsMessageCondition(
this.resolveAnnotationValues(annotation.value()), this.getPathMatcher()));
}
private SimpMessageMappingInfo createSubscribeCondition(final SubscribeMapping annotation) {
final SimpMessageTypeMessageCondition messageTypeMessageCondition = SimpMessageTypeMessageCondition.SUBSCRIBE;
return new SimpMessageMappingInfo(messageTypeMessageCondition, new DestinationPatternsMessageCondition(
this.resolveAnnotationValues(annotation.value()), this.getPathMatcher()));
}
這些方法將解決值考慮的屬性(調用resolveAnnotationValues
方法),所以我們需要使用這樣的:
private String[] resolveAnnotationValues(final String[] destinationNames) {
final int length = destinationNames.length;
final String[] result = new String[length];
for (int i = 0; i < length; i++) {
result[i] = this.resolveAnnotationValue(destinationNames[i]);
}
return result;
}
private String resolveAnnotationValue(final String name) {
if (!(this.getApplicationContext() instanceof ConfigurableApplicationContext)) {
return name;
}
final ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) this.getApplicationContext();
final ConfigurableBeanFactory configurableBeanFactory = applicationContext.getBeanFactory();
final String placeholdersResolved = configurableBeanFactory.resolveEmbeddedValue(name);
final BeanExpressionResolver exprResolver = configurableBeanFactory.getBeanExpressionResolver();
if (exprResolver == null) {
return name;
}
final Object result = exprResolver.evaluate(placeholdersResolved, new BeanExpressionContext(configurableBeanFactory, null));
return result != null ? result.toString() : name;
}
您仍然需要在您的配置中定義一個PropertySourcesPlaceholderConfigurer
bean。
如果您正在使用基於XML的配置,包括像這樣:
<context:property-placeholder location="classpath:/META-INF/spring/url-mapping-config.properties" />
如果您使用的是基於Java的配置,你可以這樣試試:
@Configuration
@PropertySources(value = @PropertySource("classpath:/META-INF/spring/url-mapping-config.properties"))
public class URLMappingConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
觀測值。:在這種情況下,url-mapping-config.properties
文件是在一個gradle產出/ Maven項目在src\main\resources\META-INF\spring
文件夾,內容是這樣的:
myPropertyWS=urlvaluews
這是我的樣本控制器:
@Controller
public class WebSocketController {
@SendTo("/topic/test")
@MessageMapping("${myPropertyWS}")
public String test() throws Exception {
Thread.sleep(4000); // simulated delay
return "OK";
}
}
在默認MessageHandler
啓動日誌會打印像這樣:
INFO: Mapped "{[/${myPropertyWS}],messageType=[MESSAGE]}" onto public java.lang.String com.brunocesar.controller.WebSocketController.test() throws java.lang.Exception
並與我們的MessageHandler
現在打印此:
INFO: Mapped "{[/urlvaluews],messageType=[MESSAGE]}" onto public java.lang.String com.brunocesar.controller.WebSocketController.test() throws java.lang.Exception
在這看到gist完整的WebSocketAnnotationMethodMessageHandler
執行。
編輯:該解決方案解決了4.2 GA
之前版本的問題。有關更多信息,請參閱this jira。
這沒有設置URL,這只是爲了傳遞一個參數。我想通過屬性指出URL,我的意思是$ {myProperty}表示完整的URL – crm86