diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java index fe01246f775..e38a1953364 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java @@ -248,7 +248,7 @@ class DefaultRestTestClient implements RestTestClient { } @Override - public RequestBodySpec apiVersion(Object version) { + public RequestBodySpec apiVersion(@Nullable Object version) { this.requestHeadersUriSpec.apiVersion(version); return this; } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/RestTestClient.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/RestTestClient.java index 7b7385b4ae6..7444b74c34b 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/RestTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/RestTestClient.java @@ -479,14 +479,19 @@ public interface RestTestClient { /** * Set an API version for the request. The version is inserted into the - * request by the {@linkplain Builder#apiVersionInserter(ApiVersionInserter) + * request through the {@link Builder#apiVersionInserter(ApiVersionInserter) * configured} {@code ApiVersionInserter}. - * @param version the API version of the request; this can be a String or - * some Object that can be formatted by the inserter — for example, - * through an {@link ApiVersionFormatter} + *

If no version is set, the + * {@link Builder#defaultApiVersion(Object) defaultApiVersion} is used, + * if configured. + *

If {@code null} is passed, then an API version is not inserted + * irrespective of default version settings. + * @param version the API version for the request; this can be a String + * or some Object that can be formatted the inserter, e.g. through an + * {@link ApiVersionFormatter}. * @return this spec for further declaration of the request */ - S apiVersion(Object version); + S apiVersion(@Nullable Object version); /** * Set the attribute with the given name to the given value. diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultRestClient.java b/spring-web/src/main/java/org/springframework/web/client/DefaultRestClient.java index bdc292be0ab..1ac20207f88 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultRestClient.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultRestClient.java @@ -293,6 +293,8 @@ final class DefaultRestClient implements RestClient { private class DefaultRequestBodyUriSpec implements RequestBodyUriSpec { + private static final Object NO_VERSION = new Object(); + private final HttpMethod httpMethod; private @Nullable URI uri; @@ -430,8 +432,8 @@ final class DefaultRestClient implements RestClient { } @Override - public RequestBodySpec apiVersion(Object version) { - this.apiVersion = version; + public RequestBodySpec apiVersion(@Nullable Object version) { + this.apiVersion = (version != null ? version : NO_VERSION); return this; } @@ -646,7 +648,15 @@ final class DefaultRestClient implements RestClient { } private @Nullable Object getApiVersionOrDefault() { - return (this.apiVersion != null ? this.apiVersion : DefaultRestClient.this.defaultApiVersion); + if (this.apiVersion == null) { + return DefaultRestClient.this.defaultApiVersion; + } + else if (this.apiVersion == NO_VERSION) { + return null; + } + else { + return this.apiVersion; + } } private @Nullable String serializeCookies() { diff --git a/spring-web/src/main/java/org/springframework/web/client/RestClient.java b/spring-web/src/main/java/org/springframework/web/client/RestClient.java index ca7c257de57..c3ad396c647 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestClient.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestClient.java @@ -642,14 +642,19 @@ public interface RestClient { /** * Set an API version for the request. The version is inserted into the - * request by the {@link Builder#apiVersionInserter(ApiVersionInserter) + * request through the {@link Builder#apiVersionInserter(ApiVersionInserter) * configured} {@code ApiVersionInserter}. - * @param version the API version of the request; this can be a String or - * some Object that can be formatted the inserter, e.g. through an + *

If no version is set, the + * {@link Builder#defaultApiVersion(Object) defaultApiVersion} is used, + * if configured. + *

If {@code null} is passed, then an API version is not inserted + * irrespective of default version settings. + * @param version the API version for the request; this can be a String + * or some Object that can be formatted the inserter, e.g. through an * {@link ApiVersionFormatter}. * @since 7.0 */ - S apiVersion(Object version); + S apiVersion(@Nullable Object version); /** * Set the attribute with the given name to the given value. diff --git a/spring-web/src/test/java/org/springframework/web/client/RestClientVersionTests.java b/spring-web/src/test/java/org/springframework/web/client/RestClientVersionTests.java index c570c183407..40890e93b29 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestClientVersionTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestClientVersionTests.java @@ -108,6 +108,15 @@ public class RestClientVersionTests { expectRequest(request -> assertThat(request.getHeaders().get("API-Version")).isEqualTo("1.2")); } + @Test + void noVersion() { + ApiVersionInserter inserter = ApiVersionInserter.useHeader("API-Version"); + RestClient restClient = restClientBuilder.defaultApiVersion(1.2).apiVersionInserter(inserter).build(); + restClient.get().uri("/path").apiVersion(null).retrieve().body(String.class); + + expectRequest(request -> assertThat(request.getHeaders().get("API-Version")).isNull()); + } + private void performRequest(ApiVersionInserter versionInserter) { restClientBuilder.apiVersionInserter(versionInserter).build() .post().uri("/path") diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java index b09cb462888..3cc7f07e57d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java @@ -206,6 +206,8 @@ final class DefaultWebClient implements WebClient { private class DefaultRequestBodyUriSpec implements RequestBodyUriSpec { + private static final Object NO_VERSION = new Object(); + private final HttpMethod httpMethod; private @Nullable URI uri; @@ -335,8 +337,8 @@ final class DefaultWebClient implements WebClient { } @Override - public DefaultRequestBodyUriSpec apiVersion(Object version) { - this.apiVersion = version; + public DefaultRequestBodyUriSpec apiVersion(@Nullable Object version) { + this.apiVersion = (version != null ? version : NO_VERSION); return this; } @@ -503,7 +505,15 @@ final class DefaultWebClient implements WebClient { } private @Nullable Object getApiVersionOrDefault() { - return (this.apiVersion != null ? this.apiVersion : DefaultWebClient.this.defaultApiVersion); + if (this.apiVersion == null) { + return DefaultWebClient.this.defaultApiVersion; + } + else if (this.apiVersion == NO_VERSION) { + return null; + } + else { + return this.apiVersion; + } } private void initHeaders(HttpHeaders out) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java index 20d073a7386..87dc4e441c4 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClient.java @@ -497,14 +497,19 @@ public interface WebClient { /** * Set an API version for the request. The version is inserted into the - * request by the {@link Builder#apiVersionInserter(ApiVersionInserter) + * request through the {@link Builder#apiVersionInserter(ApiVersionInserter) * configured} {@code ApiVersionInserter}. - * @param version the API version of the request; this can be a String or - * some Object that can be formatted the inserter, e.g. through an + *

If no version is set, the + * {@link Builder#defaultApiVersion(Object) defaultApiVersion} is used, + * if configured. + *

If {@code null} is passed, then an API version is not inserted + * irrespective of default version settings. + * @param version the API version for the request; this can be a String + * or some Object that can be formatted the inserter, e.g. through an * {@link ApiVersionFormatter}. * @since 7.0 */ - S apiVersion(Object version); + S apiVersion(@Nullable Object version); /** * Set the attribute with the given name to the given value. diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientVersionTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientVersionTests.java index 23d55259907..367d6038bf1 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientVersionTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientVersionTests.java @@ -99,6 +99,15 @@ public class WebClientVersionTests { expectRequest(request -> assertThat(request.getHeaders().get("API-Version")).isEqualTo("1.2")); } + @Test + void noVersion() { + ApiVersionInserter inserter = ApiVersionInserter.useHeader("API-Version"); + WebClient webClient = webClientBuilder.defaultApiVersion(1.2).apiVersionInserter(inserter).build(); + webClient.get().uri("/path").apiVersion(null).retrieve().bodyToMono(String.class).block(); + + expectRequest(request -> assertThat(request.getHeaders().get("API-Version")).isNull()); + } + private void performRequest(ApiVersionInserter versionInserter) { WebClient webClient = webClientBuilder.apiVersionInserter(versionInserter).build(); webClient.get().uri("/path").apiVersion(1.2).retrieve().bodyToMono(String.class).block();