使用Spring MVC RequestMappingHandlerMapping和Spring Websocket的ServletWebSocketHandlerRegistry处理相同的URL
问题内容:
我要拥有什么:
- 客户发送
GET / HTTP/1.1
(无Connection: upgrade
)-此请求应由RequestMappingHandlerMapping
- 客户端
Connection: upgrade
与GET请求一起发送-此请求应由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映射的方式替换此错误页面?还有其他配置可以使我首先描述吗?
问题答案:
问题是-当MVC控制器优先时,它总是以HTTP 200响应,WebSocket处理程序从未到达
当RequestMappingHandlerMapping
优先于时WebSocketHandlerMapping
,对于它们都可以处理的对端点的请求(如果仅考虑URL),DispatcherServlet
会将请求分派给@RequestMapping
方法,而不是WebSocket处理程序。为了解决此问题,请限制@RequestMapping
方法只提供不带Connection:Upgrade
标头的请求:
@Controller
public class Status {
@RequestMapping(value = "/", method = GET, headers = "Connection!=Upgrade")
public String status() {
return "OK";
}
}
这样,当DispatcherServlet
搜索该公共端点的处理程序时,它将考虑Connection:Upgrade
标头的存在或不存在,以确定满足请求的正确处理程序。