2015-07-02 175 views
2

我與彈簧的WebSocket工作,我有以下問題:@MessageMapping用佔位符

我試圖把一個佔位符@MessageMapping註釋裏面,以獲得從屬性的URL。它適用於@RequestMapping,但不適用於@MessageMapping

如果我使用此佔位符,則URL爲空。任何想法或建議?

例子:

@RequestMapping(value= "${myProperty}") 

@MessageMapping("${myProperty}") 

回答

0

更新

現在我明白你的意思,但我認爲這是不可能的(還)。

Documentation沒有提及與路徑映射URI相關的任何內容。

enter image description here

老答案

使用

@MessageMapping("/handler/{myProperty}") 

,而不是

@MessageMapping("/handler/${myProperty}") 

而且使用這樣的:

@MessageMapping("/myHandler/{username}") 
    public void handleTextMessage(@DestinationVariable String username,Message message) { 
     //do something 
    } 
+0

這沒有設置URL,這只是爲了傳遞一個參數。我想通過屬性指出URL,我的意思是$ {myProperty}表示完整的URL – crm86

1

Spring允許您在@RequestMapping中使用屬性佔位符,但不允許在@MessageMapping中使用屬性佔位符。這是'因爲MessageHandler。所以,我們需要覆蓋默認MessageHandler來做到這一點。

不支持佔位符,您需要自己添加此支持。

爲了簡單起見,我剛剛創建在我的項目另一WebSocketAnnotationMethodMessageHandler類在同一個包,原來,org.springframework.web.socket.messaging,並從SimpAnnotationMethodMessageHandler覆蓋getMappingForMethod方法有相同的內容,只能用這個這個方法(privateWebSocketAnnotationMethodMessageHandler如何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。

+0

它適用於@requedtmapping,但是您是否嘗試過@Messagemapping? – Karthik

+1

@bruno_cesar你嚇到我了第一個你的答案:P 我正在用4.2.0.RC1最後一個小時:P – Karthik

+0

@karthik是的,對不起:P –