使用 Spring MVC RequestMappingHandlerMapping 和 Spring Websocket 的 ServletWebSocketHandlerRegistry 处理相同的 URL

Handle the same URL with Spring MVC RequestMappingHandlerMapping and Spring Websocket's ServletWebSocketHandlerRegistry

我想要什么:

我的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("*");
    }
}

我的 webmvc 控制器:

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

问题是 - 当 MVC 控制器优先时,它总是以 HTTP 200 响应,WebSocket 处理程序从未到达。当 WebSocket 处理程序具有优先权时 - 它与 WebSocket 客户端一起工作,但是当我尝试 http 客户端(浏览器)时它以 Can "Upgrade" only to "WebSocket". 响应 是否有可能以某种方式将此错误页面替换为回退到我的 MVC 映射?还有其他配置可以实现我首先描述的内容吗?

The problem is - when MVC controller taking precedence, it always respond with HTTP 200, WebSocket handler never reached

RequestMappingHandlerMapping 优先于 WebSocketHandlerMapping 时,对于它们都可以处理的端点请求(如果只考虑 URL),DispatcherServlet会将请求分派给 @RequestMapping 方法,而不是 WebSocket 处理程序。为了解决这个问题,限制 @RequestMapping 方法只服务于没有 Connection:Upgrade header:

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

这样,当 DispatcherServlet 搜索该公共端点的处理程序时,它会考虑是否存在 Connection:Upgrade header 来确定正确的处理程序来完成请求。