2016-07-14 94 views
10

Cosa voglio avere:Maneggiare lo stesso URL con Spring MVC RequestMappingHandlerMapping e ServletWebSocketHandlerRegistry Primavera websocket

  • client invia GET/HTTP/1.1 (senza Connection: upgrade) - tale richiesta dovrebbe essere gestita da RequestMappingHandlerMapping
  • client invia Connection: upgrade lungo con richiesta GET - tale richiesta dovrebbe essere gestita da ServletWebSocketHandlerRegistry

la mia configurazione di Java:

@Configuration 
@EnableWebSocket 
public class WebsocketConfiguration extends WebMvcConfigurationSupport 
            implements WebSocketConfigurer { 
    @Bean 
    WebsocketComponent wsHandler() { 
     return new WebsocketComponent(); 
    } 

    @Override 
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 
     registry.addHandler(wsHandler(), "/").setAllowedOrigins("*"); 
    } 
} 

mio regolatore webmvc:

@Controller 
public class Status { 
    @RequestMapping(value = "/", method = RequestMethod.GET) 
    public String status() { 
     return "OK"; 
    } 
} 

Il problema è - quando il controller MVC la precedenza, si risponde sempre con HTTP 200, gestore WebSocket non ha mai raggiunto. Quando il gestore WebSocket ha la precedenza, funziona con il client WebSocket, ma quando provo il client http (browser) risponde con Can "Upgrade" only to "WebSocket". È possibile sostituire in qualche modo questa pagina di errore con fallback alla mia mappatura MVC? Qualche altra configurazione per fare ciò che ho descritto per primo?

+0

Sono sicuro del fatto che i mapping delle richieste di Spring MVC hanno precedenza più bassa rispetto ai mapping WebSocket? Ad esempio, puoi aprire una connessione socket web su 'ws: // localhost: 8080/status'? –

+0

@AliDehghani sicuro, la connessione websocket funziona, la semplice connessione http non ha funzionato con: 00:30:20 ERRORE Handshake non riuscito a causa dell'errore Intestazione aggiornamento: null – vitalyster

+0

Apparentemente, il tuo 'WebSocketHandlerMapping' ha più precedenza sul tuo' RequestMappingHandlerMapping'. Di solito è il contrario, per favore pubblica più informazioni sulle tue configurazioni –

risposta

7

Il problema è - quando il controller MVC la precedenza, è sempre rispondere con HTTP 200, gestore WebSocket non ha mai raggiunto

Quando RequestMappingHandlerMapping ha la precedenza su WebSocketHandlerMapping, per la richiesta di un endpoint che entrambi possono gestire (Se si considera solo l'URL), DispatcherServlet invierà la richiesta ai metodi @RequestMapping, non al gestore WebSocket. Per risolvere questo problema, limitare @RequestMapping metodo per servire solo la richiesta senza Connection:Upgrade intestazione:

@Controller 
public class Status { 
    @RequestMapping(value = "/", method = GET, headers = "Connection!=Upgrade") 
    public String status() { 
     return "OK"; 
    } 
} 

questo modo, quando DispatcherServlet cerca un gestore per tale endpoint comuni, sarebbe considerare la presenza o l'assenza del Connection:Upgrade intestazione per determinare il gestore di destra per soddisfare la richiesta.

+1

Ottimo, funziona! – vitalyster