mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 16:39:29 +00:00
Merge branch for PR 36084
Resolve conflicts and refactor merged code in AbstractHandlerMapping See gh-36084
This commit is contained in:
+18
-3
@@ -17,6 +17,7 @@
|
||||
package org.springframework.web.reactive.accept;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
@@ -24,17 +25,31 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
* Contract to extract the version from a request.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Jonathan Kaplan
|
||||
* @since 7.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public
|
||||
interface ApiVersionResolver {
|
||||
public interface ApiVersionResolver {
|
||||
|
||||
/**
|
||||
* Resolve the version for the given exchange.
|
||||
* This method wraps the synchronous {@code resolveVersion} method
|
||||
* and provides a reactive alternative.
|
||||
* @param exchange the current exchange
|
||||
* @return {@code Mono} emitting the version value, or an empty {@code Mono}
|
||||
* @since 7.0.3
|
||||
*/
|
||||
Mono<String> resolveApiVersion(ServerWebExchange exchange);
|
||||
|
||||
/**
|
||||
* Resolve the version for the given exchange.
|
||||
* @param exchange the current exchange
|
||||
* @return the version value, or {@code null} if not found
|
||||
* @deprecated in favor of {@link #resolveApiVersion(ServerWebExchange)}
|
||||
*/
|
||||
@Nullable String resolveVersion(ServerWebExchange exchange);
|
||||
@Deprecated(since = "7.0.3", forRemoval = true)
|
||||
default @Nullable String resolveVersion(ServerWebExchange exchange) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+53
@@ -17,6 +17,7 @@
|
||||
package org.springframework.web.reactive.accept;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.web.accept.InvalidApiVersionException;
|
||||
import org.springframework.web.accept.MissingApiVersionException;
|
||||
@@ -27,17 +28,32 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
* to manage API versioning for an application.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Jonathan Kaplan
|
||||
* @since 7.0
|
||||
* @see DefaultApiVersionStrategy
|
||||
*/
|
||||
public interface ApiVersionStrategy {
|
||||
|
||||
/**
|
||||
* Resolve the version value from a request.
|
||||
* @param exchange the current exchange
|
||||
* @return a {@code Mono} emitting the raw version as a {@code String},
|
||||
* or an empty {@code Mono} if no version is found
|
||||
* @since 7.0.3
|
||||
* @see ApiVersionResolver
|
||||
*/
|
||||
default Mono<String> resolveApiVersion(ServerWebExchange exchange) {
|
||||
return Mono.justOrEmpty(resolveVersion(exchange));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the version value from a request, e.g. from a request header.
|
||||
* @param exchange the current exchange
|
||||
* @return the version, if present or {@code null}
|
||||
* @see ApiVersionResolver
|
||||
* @deprecated as of 7.0.3, in favor of {@link #resolveApiVersion(ServerWebExchange)}
|
||||
*/
|
||||
@Deprecated(since = "7.0.3", forRemoval = true)
|
||||
@Nullable
|
||||
String resolveVersion(ServerWebExchange exchange);
|
||||
|
||||
@@ -64,12 +80,49 @@ public interface ApiVersionStrategy {
|
||||
*/
|
||||
@Nullable Comparable<?> getDefaultVersion();
|
||||
|
||||
/**
|
||||
* Convenience method to resolve, parse, and validate the request version,
|
||||
* or return the default version if configured.
|
||||
* @param exchange the current exchange
|
||||
* @return a {@code Mono} emitting the request version, a validation error,
|
||||
* or an empty {@code Mono} if there is no version
|
||||
* @since 7.0.3
|
||||
*/
|
||||
default Mono<Comparable<?>> resolveParseAndValidateApiVersion(ServerWebExchange exchange) {
|
||||
|
||||
Mono<Comparable<?>> result = resolveApiVersion(exchange)
|
||||
.map(value -> {
|
||||
Comparable<?> version;
|
||||
try {
|
||||
version = parseVersion(value);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new InvalidApiVersionException(value, null, ex);
|
||||
}
|
||||
validateVersion(version, exchange);
|
||||
return version;
|
||||
});
|
||||
|
||||
return result.switchIfEmpty(Mono.fromSupplier(() -> {
|
||||
Comparable<?> defaultVersion = getDefaultVersion();
|
||||
if (defaultVersion != null) {
|
||||
return defaultVersion;
|
||||
}
|
||||
else {
|
||||
validateVersion(null, exchange);
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to return the parsed and validated request version,
|
||||
* or the default version if configured.
|
||||
* @param exchange the current exchange
|
||||
* @return the parsed request version, or the default version
|
||||
* @deprecated in favor of {@link #resolveParseAndValidateApiVersion(ServerWebExchange)}
|
||||
*/
|
||||
@Deprecated(since = "7.0.3", forRemoval = true)
|
||||
default @Nullable Comparable<?> resolveParseAndValidateVersion(ServerWebExchange exchange) {
|
||||
String value = resolveVersion(exchange);
|
||||
Comparable<?> version;
|
||||
|
||||
+10
@@ -23,6 +23,8 @@ import java.util.TreeSet;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.accept.ApiVersionParser;
|
||||
@@ -152,6 +154,7 @@ public class DefaultApiVersionStrategy implements ApiVersionStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
@Override
|
||||
public @Nullable String resolveVersion(ServerWebExchange exchange) {
|
||||
for (ApiVersionResolver resolver : this.versionResolvers) {
|
||||
@@ -163,6 +166,13 @@ public class DefaultApiVersionStrategy implements ApiVersionStrategy {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> resolveApiVersion(ServerWebExchange exchange) {
|
||||
return Flux.fromIterable(this.versionResolvers)
|
||||
.flatMap(resolver -> resolver.resolveApiVersion(exchange))
|
||||
.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparable<?> parseVersion(String version) {
|
||||
return this.versionParser.parseVersion(version);
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
*/
|
||||
public class HeaderApiVersionResolver implements ApiVersionResolver {
|
||||
public class HeaderApiVersionResolver implements SyncApiVersionResolver {
|
||||
|
||||
private final String headerName;
|
||||
|
||||
@@ -37,7 +37,7 @@ public class HeaderApiVersionResolver implements ApiVersionResolver {
|
||||
|
||||
|
||||
@Override
|
||||
public @Nullable String resolveVersion(ServerWebExchange exchange) {
|
||||
public @Nullable String resolveVersionValue(ServerWebExchange exchange) {
|
||||
return exchange.getRequest().getHeaders().getFirst(this.headerName);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
*/
|
||||
public class MediaTypeParamApiVersionResolver implements ApiVersionResolver {
|
||||
public class MediaTypeParamApiVersionResolver implements SyncApiVersionResolver {
|
||||
|
||||
private final MediaType compatibleMediaType;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class MediaTypeParamApiVersionResolver implements ApiVersionResolver {
|
||||
|
||||
|
||||
@Override
|
||||
public @Nullable String resolveVersion(ServerWebExchange exchange) {
|
||||
public @Nullable String resolveVersionValue(ServerWebExchange exchange) {
|
||||
HttpHeaders headers = exchange.getRequest().getHeaders();
|
||||
for (MediaType mediaType : headers.getAccept()) {
|
||||
if (this.compatibleMediaType.isCompatibleWith(mediaType)) {
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
*/
|
||||
public class PathApiVersionResolver implements ApiVersionResolver {
|
||||
public class PathApiVersionResolver implements SyncApiVersionResolver {
|
||||
|
||||
private final int pathSegmentIndex;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class PathApiVersionResolver implements ApiVersionResolver {
|
||||
|
||||
|
||||
@Override
|
||||
public String resolveVersion(ServerWebExchange exchange) {
|
||||
public String resolveVersionValue(ServerWebExchange exchange) {
|
||||
int i = 0;
|
||||
for (PathContainer.Element e : exchange.getRequest().getPath().pathWithinApplication().elements()) {
|
||||
if (e instanceof PathContainer.PathSegment && i++ == this.pathSegmentIndex) {
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
*/
|
||||
public class QueryApiVersionResolver implements ApiVersionResolver {
|
||||
public class QueryApiVersionResolver implements SyncApiVersionResolver {
|
||||
|
||||
private final String queryParamName;
|
||||
|
||||
@@ -37,7 +37,7 @@ public class QueryApiVersionResolver implements ApiVersionResolver {
|
||||
|
||||
|
||||
@Override
|
||||
public @Nullable String resolveVersion(ServerWebExchange exchange) {
|
||||
public @Nullable String resolveVersionValue(ServerWebExchange exchange) {
|
||||
return exchange.getRequest().getQueryParams().getFirst(this.queryParamName);
|
||||
}
|
||||
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.reactive.accept;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* An extension of {@link ApiVersionResolver}s for implementations that can
|
||||
* resolve the version in an imperative way without blocking.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0.3
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SyncApiVersionResolver extends ApiVersionResolver {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This method delegates to the synchronous
|
||||
* {@link #resolveVersionValue} and wraps the result as {@code Mono}.
|
||||
*/
|
||||
@Override
|
||||
default Mono<String> resolveApiVersion(ServerWebExchange exchange) {
|
||||
return Mono.justOrEmpty(resolveVersionValue(exchange));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the version for the given exchange imperatively without blocking.
|
||||
* @param exchange the current exchange
|
||||
* @return the version value, or {@code null} if not found
|
||||
*/
|
||||
@Nullable String resolveVersionValue(ServerWebExchange exchange);
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
@Override
|
||||
default @Nullable String resolveVersion(ServerWebExchange exchange) {
|
||||
return resolveVersionValue(exchange);
|
||||
}
|
||||
|
||||
}
|
||||
+40
-46
@@ -185,54 +185,48 @@ public abstract class AbstractHandlerMapping extends ApplicationObjectSupport
|
||||
|
||||
@Override
|
||||
public Mono<Object> getHandler(ServerWebExchange exchange) {
|
||||
ApiVersionHolder versionHolder = initApiVersion(exchange);
|
||||
return getHandlerInternal(exchange).map(handler -> {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(exchange.getLogPrefix() + "Mapped to " + handler);
|
||||
}
|
||||
if (versionHolder.hasError()) {
|
||||
throw versionHolder.getError();
|
||||
}
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
|
||||
CorsConfiguration config = (this.corsConfigurationSource != null ?
|
||||
this.corsConfigurationSource.getCorsConfiguration(exchange) : null);
|
||||
CorsConfiguration handlerConfig = getCorsConfiguration(handler, exchange);
|
||||
config = (config != null ? config.combine(handlerConfig) : handlerConfig);
|
||||
if (config != null) {
|
||||
config.validateAllowCredentials();
|
||||
config.validateAllowPrivateNetwork();
|
||||
}
|
||||
if (!this.corsProcessor.process(config, exchange) || CorsUtils.isPreFlightRequest(request)) {
|
||||
return NO_OP_HANDLER;
|
||||
}
|
||||
}
|
||||
if (getApiVersionStrategy() != null) {
|
||||
if (versionHolder.hasVersion()) {
|
||||
Comparable<?> version = versionHolder.getVersion();
|
||||
getApiVersionStrategy().handleDeprecations(version, handler, exchange);
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
});
|
||||
return initApiVersion(exchange).flatMap(versionHolder ->
|
||||
getHandlerInternal(exchange).map(handler -> {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(exchange.getLogPrefix() + "Mapped to " + handler);
|
||||
}
|
||||
if (versionHolder.hasError()) {
|
||||
throw versionHolder.getError();
|
||||
}
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
|
||||
CorsConfiguration config = (this.corsConfigurationSource != null ?
|
||||
this.corsConfigurationSource.getCorsConfiguration(exchange) : null);
|
||||
CorsConfiguration handlerConfig = getCorsConfiguration(handler, exchange);
|
||||
config = (config != null ? config.combine(handlerConfig) : handlerConfig);
|
||||
if (config != null) {
|
||||
config.validateAllowCredentials();
|
||||
config.validateAllowPrivateNetwork();
|
||||
}
|
||||
if (!this.corsProcessor.process(config, exchange) || CorsUtils.isPreFlightRequest(request)) {
|
||||
return NO_OP_HANDLER;
|
||||
}
|
||||
}
|
||||
if (getApiVersionStrategy() != null) {
|
||||
if (versionHolder.hasVersion()) {
|
||||
Comparable<?> version = versionHolder.getVersion();
|
||||
getApiVersionStrategy().handleDeprecations(version, handler, exchange);
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
}));
|
||||
}
|
||||
|
||||
private ApiVersionHolder initApiVersion(ServerWebExchange exchange) {
|
||||
ApiVersionHolder versionHolder;
|
||||
if (this.apiVersionStrategy == null) {
|
||||
versionHolder = ApiVersionHolder.EMPTY;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Comparable<?> version = this.apiVersionStrategy.resolveParseAndValidateVersion(exchange);
|
||||
versionHolder = ApiVersionHolder.fromVersion(version);
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
versionHolder = ApiVersionHolder.fromError(ex);
|
||||
}
|
||||
}
|
||||
exchange.getAttributes().put(API_VERSION_ATTRIBUTE, versionHolder);
|
||||
return versionHolder;
|
||||
private Mono<ApiVersionHolder> initApiVersion(ServerWebExchange exchange) {
|
||||
|
||||
Mono<ApiVersionHolder> holderMono = (this.apiVersionStrategy != null ?
|
||||
this.apiVersionStrategy.resolveParseAndValidateApiVersion(exchange)
|
||||
.map(ApiVersionHolder::fromVersion)
|
||||
.onErrorResume(RuntimeException.class, ex -> Mono.just(ApiVersionHolder.fromError(ex))) :
|
||||
Mono.just(ApiVersionHolder.EMPTY));
|
||||
|
||||
return holderMono.doOnNext(holder ->
|
||||
exchange.getAttributes().put(HandlerMapping.API_VERSION_ATTRIBUTE, holder));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+37
-23
@@ -21,6 +21,8 @@ import java.util.function.Predicate;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.web.accept.InvalidApiVersionException;
|
||||
import org.springframework.web.accept.MissingApiVersionException;
|
||||
@@ -30,11 +32,11 @@ import org.springframework.web.testfixture.server.MockServerWebExchange;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link org.springframework.web.accept.DefaultApiVersionStrategy}.
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Jonathan Kaplan
|
||||
*/
|
||||
public class DefaultApiVersionStrategiesTests {
|
||||
|
||||
@@ -50,9 +52,11 @@ public class DefaultApiVersionStrategiesTests {
|
||||
|
||||
@Test
|
||||
void missingRequiredVersion() {
|
||||
assertThatThrownBy(() -> testValidate(null, apiVersionStrategy()))
|
||||
.isInstanceOf(MissingApiVersionException.class)
|
||||
.hasMessage("400 BAD_REQUEST \"API version is required.\"");
|
||||
StepVerifier.create(testValidate(null, apiVersionStrategy()))
|
||||
.expectErrorSatisfies(ex -> assertThat(ex)
|
||||
.isInstanceOf(MissingApiVersionException.class)
|
||||
.hasMessage(("400 BAD_REQUEST \"API version is required.\"")))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -60,21 +64,25 @@ public class DefaultApiVersionStrategiesTests {
|
||||
String version = "1.2";
|
||||
DefaultApiVersionStrategy strategy = apiVersionStrategy();
|
||||
strategy.addSupportedVersion(version);
|
||||
testValidate(version, strategy);
|
||||
Mono<String> result = testValidate(version, strategy);
|
||||
StepVerifier.create(result).expectNext("1.2.0").verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateSupportedVersionForDefaultVersion() {
|
||||
String defaultVersion = "1.2";
|
||||
DefaultApiVersionStrategy strategy = apiVersionStrategy(defaultVersion, false, null);
|
||||
testValidate(defaultVersion, strategy);
|
||||
Mono<String> result = testValidate(defaultVersion, strategy);
|
||||
StepVerifier.create(result).expectNext("1.2.0").verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateUnsupportedVersion() {
|
||||
assertThatThrownBy(() -> testValidate("1.2", apiVersionStrategy()))
|
||||
.isInstanceOf(InvalidApiVersionException.class)
|
||||
.hasMessage("400 BAD_REQUEST \"Invalid API version: '1.2.0'.\"");
|
||||
StepVerifier.create(testValidate("1.2", apiVersionStrategy()))
|
||||
.expectErrorSatisfies(ex -> assertThat(ex)
|
||||
.isInstanceOf(InvalidApiVersionException.class)
|
||||
.hasMessage(("400 BAD_REQUEST \"Invalid API version: '1.2.0'.\"")))
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -82,7 +90,8 @@ public class DefaultApiVersionStrategiesTests {
|
||||
String version = "1.2";
|
||||
DefaultApiVersionStrategy strategy = apiVersionStrategy(null, true, null);
|
||||
strategy.addMappedVersion(version);
|
||||
testValidate(version, strategy);
|
||||
Mono<String> result = testValidate(version, strategy);
|
||||
StepVerifier.create(result).expectNext("1.2.0").verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,28 +99,32 @@ public class DefaultApiVersionStrategiesTests {
|
||||
String version = "1.2";
|
||||
DefaultApiVersionStrategy strategy = apiVersionStrategy();
|
||||
strategy.addMappedVersion(version);
|
||||
assertThatThrownBy(() -> testValidate(version, strategy)).isInstanceOf(InvalidApiVersionException.class);
|
||||
Mono<String> result = testValidate(version, strategy);
|
||||
StepVerifier.create(result).expectError(InvalidApiVersionException.class).verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateSupportedWithPredicate() {
|
||||
SemanticApiVersionParser.Version parsedVersion = parser.parseVersion("1.2");
|
||||
testValidate("1.2", apiVersionStrategy(null, false, version -> version.equals(parsedVersion)));
|
||||
ApiVersionStrategy strategy = apiVersionStrategy(null, false, version -> version.equals(parsedVersion));
|
||||
Mono<String> result = testValidate("1.2", strategy);
|
||||
StepVerifier.create(result).expectNext("1.2.0").verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateUnsupportedWithPredicate() {
|
||||
DefaultApiVersionStrategy strategy = apiVersionStrategy(null, false, version -> version.equals("1.2"));
|
||||
assertThatThrownBy(() -> testValidate("1.2", strategy)).isInstanceOf(InvalidApiVersionException.class);
|
||||
ApiVersionStrategy strategy = apiVersionStrategy(null, false, version -> version.equals("1.2"));
|
||||
Mono<?> result = testValidate("1.2", strategy);
|
||||
StepVerifier.create(result).verifyError(InvalidApiVersionException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void versionRequiredAndDefaultVersionSet() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() ->
|
||||
new org.springframework.web.accept.DefaultApiVersionStrategy(
|
||||
List.of(request -> request.getParameter("api-version")), new SemanticApiVersionParser(),
|
||||
true, "1.2", true, version -> true, null))
|
||||
.isThrownBy(() -> {
|
||||
ApiVersionResolver resolver = new QueryApiVersionResolver("api-version");
|
||||
new DefaultApiVersionStrategy(List.of(resolver), parser, true, "1.2", true, v -> true, null);
|
||||
})
|
||||
.withMessage("versionRequired cannot be set to true if a defaultVersion is also configured");
|
||||
}
|
||||
|
||||
@@ -124,16 +137,17 @@ public class DefaultApiVersionStrategiesTests {
|
||||
@Nullable Predicate<Comparable<?>> supportedVersionPredicate) {
|
||||
|
||||
return new DefaultApiVersionStrategy(
|
||||
List.of(exchange -> exchange.getRequest().getQueryParams().getFirst("api-version")),
|
||||
List.of(new QueryApiVersionResolver("api-version")),
|
||||
parser, null, defaultVersion, detectSupportedVersions, supportedVersionPredicate, null);
|
||||
}
|
||||
|
||||
private void testValidate(@Nullable String version, DefaultApiVersionStrategy strategy) {
|
||||
MockServerHttpRequest.BaseBuilder<?> requestBuilder = MockServerHttpRequest.get("/");
|
||||
private Mono<String> testValidate(@Nullable String version, ApiVersionStrategy strategy) {
|
||||
MockServerHttpRequest.BaseBuilder<?> builder = MockServerHttpRequest.get("/");
|
||||
if (version != null) {
|
||||
requestBuilder.queryParam("api-version", version);
|
||||
builder.queryParam("api-version", version);
|
||||
}
|
||||
strategy.resolveParseAndValidateVersion(MockServerWebExchange.builder(requestBuilder).build());
|
||||
MockServerWebExchange exchange = MockServerWebExchange.builder(builder).build();
|
||||
return strategy.resolveParseAndValidateApiVersion(exchange).map(Object::toString);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
@@ -381,7 +382,7 @@ class RequestPredicatesTests {
|
||||
|
||||
private static DefaultApiVersionStrategy apiVersionStrategy() {
|
||||
return new DefaultApiVersionStrategy(
|
||||
List.of(exchange -> null), new SemanticApiVersionParser(), true, null, false, null, null);
|
||||
List.of(exchange -> Mono.empty()), new SemanticApiVersionParser(), true, null, false, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -29,6 +29,7 @@ import org.springframework.web.accept.NotAcceptableApiVersionException;
|
||||
import org.springframework.web.accept.SemanticApiVersionParser;
|
||||
import org.springframework.web.reactive.HandlerMapping;
|
||||
import org.springframework.web.reactive.accept.DefaultApiVersionStrategy;
|
||||
import org.springframework.web.reactive.accept.QueryApiVersionResolver;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.web.testfixture.server.MockServerWebExchange;
|
||||
@@ -52,7 +53,7 @@ public class VersionRequestConditionTests {
|
||||
|
||||
private static DefaultApiVersionStrategy initVersionStrategy(@Nullable String defaultVersion) {
|
||||
return new DefaultApiVersionStrategy(
|
||||
List.of(exchange -> exchange.getRequest().getQueryParams().getFirst("api-version")),
|
||||
List.of(new QueryApiVersionResolver("api-version")),
|
||||
new SemanticApiVersionParser(), null, defaultVersion, false, null, null);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user