diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java index c91b12891297..1668d1c7042c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java @@ -373,7 +373,8 @@ protected RequestMappingInfo createRequestMappingInfo( .methods(toMethodArray(httpExchange.method())) .consumes(toStringArray(httpExchange.contentType())) .produces(httpExchange.accept()) - .headers(httpExchange.headers()); + .headers(httpExchange.headers()) + .version(httpExchange.version()); if (customCondition != null) { builder.customCondition(customCondition); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMappingTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMappingTests.java index ea5225e8b419..1cbb80095914 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMappingTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMappingTests.java @@ -58,6 +58,7 @@ import org.springframework.web.reactive.result.condition.MediaTypeExpression; import org.springframework.web.reactive.result.method.RequestMappingInfo; import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.service.annotation.GetExchange; import org.springframework.web.service.annotation.HttpExchange; import org.springframework.web.service.annotation.PostExchange; import org.springframework.web.service.annotation.PutExchange; @@ -130,6 +131,34 @@ void versionInvalid() { .verifyError(InvalidApiVersionException.class); } + @Test + void httpExchangeWithVersion() { + DefaultApiVersionStrategy versionStrategy = new DefaultApiVersionStrategy( + List.of(new HeaderApiVersionResolver("API-Version")), new SemanticApiVersionParser(), + true, null, true, null, null); + this.handlerMapping.setApiVersionStrategy(versionStrategy); + this.handlerMapping.afterPropertiesSet(); + + Class clazz = HttpExchangeController.class; + Method method = ReflectionUtils.findMethod(clazz, "versionedExchange"); + RequestMappingInfo mappingInfo = this.handlerMapping.getMappingForMethod(method, clazz); + + assertThat(mappingInfo).isNotNull(); + assertThat(mappingInfo.getVersionCondition().getVersion()).isEqualTo("1.1"); + } + + @Test + void httpExchangeWithoutVersionHasNoVersionCondition() { + this.handlerMapping.afterPropertiesSet(); + + Class clazz = HttpExchangeController.class; + Method method = ReflectionUtils.findMethod(clazz, "defaultValuesExchange"); + RequestMappingInfo mappingInfo = this.handlerMapping.getMappingForMethod(method, clazz); + + assertThat(mappingInfo).isNotNull(); + assertThat(mappingInfo.getVersionCondition().getVersion()).isNull(); + } + private ServerWebExchange initExchangeForVersionTest(String version) { ((StaticWebApplicationContext) this.handlerMapping.getApplicationContext()) @@ -640,6 +669,11 @@ public void customValuesExchange(){} public String customHeadersExchange() { return "info"; } + + @GetExchange(version = "1.1") + public String versionedExchange() { + return "v1.1"; + } } @HttpExchange("/exchange") diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java index 79a7ef4fe9c4..2a21215be681 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java @@ -400,7 +400,8 @@ protected RequestMappingInfo createRequestMappingInfo( .methods(toMethodArray(httpExchange.method())) .consumes(toStringArray(httpExchange.contentType())) .produces(httpExchange.accept()) - .headers(httpExchange.headers()); + .headers(httpExchange.headers()) + .version(httpExchange.version()); if (customCondition != null) { builder.customCondition(customCondition); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMappingTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMappingTests.java index 249cab04570b..d92f65416542 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMappingTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMappingTests.java @@ -51,6 +51,7 @@ import org.springframework.web.context.support.StaticWebApplicationContext; import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerTypePredicate; +import org.springframework.web.service.annotation.GetExchange; import org.springframework.web.service.annotation.HttpExchange; import org.springframework.web.service.annotation.PostExchange; import org.springframework.web.service.annotation.PutExchange; @@ -169,22 +170,36 @@ private void initRequestPath(RequestMappingHandlerMapping mapping, MockHttpServl @PathPatternsParameterizedTest void version(RequestMappingHandlerMapping mapping) throws Exception { - MockHttpServletRequest request = initRequestForVersionTest(mapping, "1.1"); + MockHttpServletRequest request = initRequestForVersionTest(mapping, VersionController.class, "1.1"); HandlerMethod handlerMethod = (HandlerMethod) mapping.getHandler(request).getHandler(); assertThat(handlerMethod.getMethod().getName()).isEqualTo("foo1_1"); } @PathPatternsParameterizedTest void versionInvalid(RequestMappingHandlerMapping mapping) throws Exception { - MockHttpServletRequest request = initRequestForVersionTest(mapping, "99"); + MockHttpServletRequest request = initRequestForVersionTest(mapping, VersionController.class, "99"); assertThatThrownBy(() -> mapping.getHandler(request)).isInstanceOf(InvalidApiVersionException.class); } + @PathPatternsParameterizedTest + void versionWithHttpExchange(RequestMappingHandlerMapping mapping) throws Exception { + MockHttpServletRequest request = initRequestForVersionTest(mapping, VersionHttpExchangeController.class, "1.1"); + HandlerMethod handlerMethod = (HandlerMethod) mapping.getHandler(request).getHandler(); + assertThat(handlerMethod.getMethod().getName()).isEqualTo("foo1_1"); + } + + @PathPatternsParameterizedTest + void versionInvalidWithHttpExchange(RequestMappingHandlerMapping mapping) { + MockHttpServletRequest request = initRequestForVersionTest(mapping, VersionHttpExchangeController.class, "99"); + assertThatThrownBy(() -> mapping.getHandler(request)).isInstanceOf(InvalidApiVersionException.class); + } + + private static MockHttpServletRequest initRequestForVersionTest( - RequestMappingHandlerMapping mapping, String version) { + RequestMappingHandlerMapping mapping, Class controllerClass, String version) { ((StaticWebApplicationContext) mapping.getApplicationContext()) - .registerSingleton("controller", VersionController.class); + .registerSingleton("controller", controllerClass); DefaultApiVersionStrategy versionStrategy = new DefaultApiVersionStrategy( List.of(new HeaderApiVersionResolver("API-Version")), new SemanticApiVersionParser(), @@ -679,6 +694,22 @@ public String foo1_1() { } + @RestController + @HttpExchange("/foo") + static class VersionHttpExchangeController { + + @GetExchange + public String foo() { + return "foo"; + } + + @GetExchange(version = "1.1") + public String foo1_1() { + return "foo1_1"; + } + } + + @RestController @HttpExchange("/exchange") static class HttpExchangeController {