mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-10-02 23:39:34 +00:00
Merge branch '4.0.x'
Closes gh-50127
This commit is contained in:
+4
-2
@@ -284,7 +284,7 @@ The same `@Controller` path can be mapped multiple times to support different ve
|
||||
For more details see {url-spring-framework-docs}/web/webflux/controller/ann-requestmapping.html#webflux-ann-requestmapping-version[Spring Framework's reference documentation].
|
||||
|
||||
Once mappings have been added, you additionally need to configure Spring WebFlux so that it is able to use any version information sent with a request.
|
||||
Typically, versions are sent as HTTP headers, query parameters or as part of the path.
|
||||
Typically, versions are sent as HTTP headers, query parameters, media type parameters, or as part of the path.
|
||||
|
||||
To configure Spring WebFlux, you can either use a javadoc:org.springframework.web.reactive.config.WebFluxConfigurer[] bean and override the `configureApiVersioning(...)` method, or you can use properties.
|
||||
|
||||
@@ -300,7 +300,9 @@ spring:
|
||||
header: X-Version
|
||||
----
|
||||
|
||||
For more complete control, you can also define javadoc:org.springframework.web.reactive.accept.ApiVersionResolver[], javadoc:org.springframework.web.accept.ApiVersionParser[] and javadoc:org.springframework.web.reactive.accept.ApiVersionDeprecationHandler[] beans which will be injected into the auto-configured Spring MVC configuration.
|
||||
NOTE: If your setup requires multiple strategies, such as header and query parameter, consider declaring the order programmatically by overriding the `configureApiVersioning` method.
|
||||
|
||||
For more complete control, you can also define javadoc:org.springframework.web.reactive.accept.ApiVersionResolver[], javadoc:org.springframework.web.accept.ApiVersionParser[] and javadoc:org.springframework.web.reactive.accept.ApiVersionDeprecationHandler[] beans which will be injected into the auto-configured Spring WebFlux configuration.
|
||||
|
||||
TIP: API versioning is also supported on the client-side with both `WebClient` and `RestClient`.
|
||||
See xref:io/rest-client.adoc#io.rest-client.apiversioning[] for details.
|
||||
|
||||
+4
-2
@@ -474,8 +474,8 @@ The same `@Controller` path can be mapped multiple times to support different ve
|
||||
|
||||
For more details see {url-spring-framework-docs}/web/webmvc/mvc-controller/ann-requestmapping.html#mvc-ann-requestmapping-version[Spring Framework's reference documentation].
|
||||
|
||||
One mappings have been added, you additionally need to configure Spring MVC so that it is able to use any version information sent with a request.
|
||||
Typically, versions are sent as HTTP headers, query parameters or as part of the path.
|
||||
Once mappings have been added, you additionally need to configure Spring MVC so that it is able to use any version information sent with a request.
|
||||
Typically, versions are sent as HTTP headers, query parameters, media type parameters, or as part of the path.
|
||||
|
||||
To configure Spring MVC, you can either use a javadoc:org.springframework.web.servlet.config.annotation.WebMvcConfigurer[] bean and override the `configureApiVersioning(...)` method, or you can use properties.
|
||||
|
||||
@@ -491,6 +491,8 @@ spring:
|
||||
header: X-Version
|
||||
----
|
||||
|
||||
NOTE: If your setup requires multiple strategies, such as header and query parameter, consider declaring the order programmatically by overriding the `configureApiVersioning` method.
|
||||
|
||||
For more complete control, you can also define javadoc:org.springframework.web.accept.ApiVersionResolver[], javadoc:org.springframework.web.accept.ApiVersionParser[] and javadoc:org.springframework.web.accept.ApiVersionDeprecationHandler[] beans which will be injected into the auto-configured Spring MVC configuration.
|
||||
|
||||
TIP: API versioning is also supported with both `WebClient` and `RestClient`.
|
||||
|
||||
+1
-2
@@ -301,9 +301,8 @@ public final class WebFluxAutoConfiguration {
|
||||
PropertyMapper map = PropertyMapper.get();
|
||||
map.from(use::getHeader).whenHasText().to(configurer::useRequestHeader);
|
||||
map.from(use::getQueryParameter).whenHasText().to(configurer::useQueryParam);
|
||||
use.getMediaTypeParameter().forEach(configurer::useMediaTypeParameter);
|
||||
map.from(use::getPathSegment).to(configurer::usePathSegment);
|
||||
use.getMediaTypeParameter()
|
||||
.forEach((mediaType, parameterName) -> configurer.useMediaTypeParameter(mediaType, parameterName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+29
@@ -909,6 +909,35 @@ class WebFluxAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void apiVersionUsesPathSegmentLast() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.webflux.apiversion.use.path-segment=1",
|
||||
"spring.webflux.apiversion.use.header=hv", "spring.webflux.apiversion.use.query-parameter=rpv",
|
||||
"spring.webflux.apiversion.use.media-type-parameter[application/json]=mtpv")
|
||||
.run((context) -> {
|
||||
DefaultApiVersionStrategy versionStrategy = context.getBean("webFluxApiVersionStrategy",
|
||||
DefaultApiVersionStrategy.class);
|
||||
|
||||
MockServerWebExchange requestWithHeader = MockServerWebExchange
|
||||
.from(MockServerHttpRequest.get("https://example.com/test/456").header("hv", "123"));
|
||||
assertThat(versionStrategy.resolveVersion(requestWithHeader)).isEqualTo("123");
|
||||
|
||||
MockServerWebExchange requestWithQueryParameter = MockServerWebExchange
|
||||
.from(MockServerHttpRequest.get("https://example.com?rpv=123"));
|
||||
assertThat(versionStrategy.resolveVersion(requestWithQueryParameter)).isEqualTo("123");
|
||||
|
||||
MockServerWebExchange requestWithMediaType = MockServerWebExchange
|
||||
.from(MockServerHttpRequest.get("https://example.com/test/456")
|
||||
.header("content-type", "application/json;mtpv=123"));
|
||||
assertThat(versionStrategy.resolveVersion(requestWithMediaType)).isEqualTo("123");
|
||||
|
||||
MockServerWebExchange requestFallbacksToApiSegment = MockServerWebExchange
|
||||
.from(MockServerHttpRequest.get("https://example.com/test/456"));
|
||||
assertThat(versionStrategy.resolveVersion(requestFallbacksToApiSegment)).isEqualTo("456");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void apiVersionBeansAreInjected() {
|
||||
this.contextRunner.withUserConfiguration(ApiVersionConfiguration.class).run((context) -> {
|
||||
|
||||
+1
-1
@@ -421,8 +421,8 @@ public final class WebMvcAutoConfiguration {
|
||||
PropertyMapper map = PropertyMapper.get();
|
||||
map.from(use::getHeader).whenHasText().to(configurer::useRequestHeader);
|
||||
map.from(use::getQueryParameter).whenHasText().to(configurer::useQueryParam);
|
||||
map.from(use::getPathSegment).to(configurer::usePathSegment);
|
||||
use.getMediaTypeParameter().forEach(configurer::useMediaTypeParameter);
|
||||
map.from(use::getPathSegment).to(configurer::usePathSegment);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
+36
@@ -1122,6 +1122,42 @@ class WebMvcAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void apiVersionUsesPathSegmentLast() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.mvc.apiversion.use.path-segment=1", "spring.mvc.apiversion.use.header=hv",
|
||||
"spring.mvc.apiversion.use.query-parameter=rpv",
|
||||
"spring.mvc.apiversion.use.media-type-parameter[application/json]=mtpv")
|
||||
.run((context) -> {
|
||||
ApiVersionStrategy versionStrategy = context.getBean("mvcApiVersionStrategy", ApiVersionStrategy.class);
|
||||
|
||||
MockHttpServletRequest requestWithHeader = new MockHttpServletRequest("GET",
|
||||
"https://example.com/test/456");
|
||||
requestWithHeader.addHeader("hv", "123");
|
||||
ServletRequestPathUtils.setParsedRequestPath(RequestPath.parse("/test/456", "/"), requestWithHeader);
|
||||
assertThat(versionStrategy.resolveVersion(requestWithHeader)).isEqualTo("123");
|
||||
|
||||
MockHttpServletRequest requestWithQueryParameter = new MockHttpServletRequest("GET",
|
||||
"https://example.com/test/456");
|
||||
requestWithQueryParameter.setQueryString("rpv=123");
|
||||
ServletRequestPathUtils.setParsedRequestPath(RequestPath.parse("/test/456", "/"),
|
||||
requestWithQueryParameter);
|
||||
assertThat(versionStrategy.resolveVersion(requestWithQueryParameter)).isEqualTo("123");
|
||||
|
||||
MockHttpServletRequest requestWithMediaType = new MockHttpServletRequest("GET",
|
||||
"https://example.com/test/456");
|
||||
ServletRequestPathUtils.setParsedRequestPath(RequestPath.parse("/test/456", "/"), requestWithMediaType);
|
||||
requestWithMediaType.addHeader(HttpHeaders.CONTENT_TYPE, "application/json;mtpv=123");
|
||||
assertThat(versionStrategy.resolveVersion(requestWithMediaType)).isEqualTo("123");
|
||||
|
||||
MockHttpServletRequest requestFallbacksToApiSegment = new MockHttpServletRequest("GET",
|
||||
"https://example.com/test/456");
|
||||
ServletRequestPathUtils.setParsedRequestPath(RequestPath.parse("/test/456", "/"),
|
||||
requestFallbacksToApiSegment);
|
||||
assertThat(versionStrategy.resolveVersion(requestFallbacksToApiSegment)).isEqualTo("456");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void apiVersionBeansAreInjected() {
|
||||
this.contextRunner.withUserConfiguration(ApiVersionConfiguration.class).run((context) -> {
|
||||
|
||||
Reference in New Issue
Block a user