From 353acbd9dee781756b9e7f3eb26c8bbb024d2ab4 Mon Sep 17 00:00:00 2001 From: Martin Mois Date: Fri, 27 Feb 2026 22:19:27 +0100 Subject: [PATCH 1/9] new method usePathSegment(int index, Predicate excludePath) in ApiVersionConfigurer to exclude certain paths Signed-off-by: Martin Mois Signed-off-by: Martin Mois --- .idea/icon.svg | 52 ------------------- .../accept/PathApiVersionResolver.java | 24 ++++++++- .../reactive/config/ApiVersionConfigurer.java | 15 ++++++ .../accept/PathApiVersionResolverTests.java | 37 +++++++++++++ 4 files changed, 74 insertions(+), 54 deletions(-) delete mode 100644 .idea/icon.svg diff --git a/.idea/icon.svg b/.idea/icon.svg deleted file mode 100644 index 89da1f709357..000000000000 --- a/.idea/icon.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - -icon-framework - - - - - - diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java index 2da6819498bf..3c71446d77bf 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java @@ -16,11 +16,15 @@ package org.springframework.web.reactive.accept; +import org.jspecify.annotations.Nullable; import org.springframework.http.server.PathContainer; +import org.springframework.http.server.RequestPath; import org.springframework.util.Assert; import org.springframework.web.accept.InvalidApiVersionException; import org.springframework.web.server.ServerWebExchange; +import java.util.function.Predicate; + /** * {@link ApiVersionResolver} that extract the version from a path segment. * @@ -30,11 +34,13 @@ * cannot yield to other resolvers. * * @author Rossen Stoyanchev + * @author Martin Mois * @since 7.0 */ public class PathApiVersionResolver implements ApiVersionResolver { private final int pathSegmentIndex; + private @Nullable Predicate excludePath = null; /** @@ -47,11 +53,25 @@ public PathApiVersionResolver(int pathSegmentIndex) { this.pathSegmentIndex = pathSegmentIndex; } + /** + * Create a resolver instance. + * @param pathSegmentIndex the index of the path segment that contains the API version + * @param excludePath a {@link Predicate} that tests if the given path should be excluded + */ + public PathApiVersionResolver(int pathSegmentIndex, Predicate excludePath) { + this(pathSegmentIndex); + this.excludePath = excludePath; + } + @Override - public String resolveVersion(ServerWebExchange exchange) { + public @Nullable String resolveVersion(ServerWebExchange exchange) { int i = 0; - for (PathContainer.Element e : exchange.getRequest().getPath().pathWithinApplication().elements()) { + RequestPath path = exchange.getRequest().getPath(); + if (this.excludePath != null && this.excludePath.test(path)) { + return null; + } + for (PathContainer.Element e : path.pathWithinApplication().elements()) { if (e instanceof PathContainer.PathSegment && i++ == this.pathSegmentIndex) { return e.value(); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ApiVersionConfigurer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ApiVersionConfigurer.java index 59351a43aa3c..1dd4a3dba6f9 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ApiVersionConfigurer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ApiVersionConfigurer.java @@ -27,6 +27,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.http.MediaType; +import org.springframework.http.server.RequestPath; import org.springframework.util.Assert; import org.springframework.web.accept.ApiVersionParser; import org.springframework.web.accept.InvalidApiVersionException; @@ -108,6 +109,20 @@ public ApiVersionConfigurer usePathSegment(int index) { return this; } + /** + * Add a resolver that extracts the API version from a path segment + * and that allows to exclude certain paths based on the provided {@link Predicate}. + *

Note that this resolver never returns {@code null}, and therefore + * cannot yield to other resolvers, see {@link org.springframework.web.accept.PathApiVersionResolver}. + * @param index the index of the path segment to check; e.g. for URL's like + * {@code "/{version}/..."} use index 0, for {@code "/api/{version}/..."} index 1. + * @param excludePath a {@link Predicate} that allows to exclude certain paths + */ + public ApiVersionConfigurer usePathSegment(int index, Predicate excludePath) { + this.versionResolvers.add(new PathApiVersionResolver(index, excludePath)); + return this; + } + /** * Add custom resolvers to resolve the API version. * @param resolvers the resolvers to use diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java index 3e3ec3076fa5..437bb792903e 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java @@ -18,17 +18,21 @@ import org.junit.jupiter.api.Test; +import org.springframework.http.server.PathContainer; import org.springframework.web.accept.InvalidApiVersionException; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest; import org.springframework.web.testfixture.server.MockServerWebExchange; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Unit tests for {@link org.springframework.web.accept.PathApiVersionResolver}. * @author Rossen Stoyanchev + * @author Martin Mois */ public class PathApiVersionResolverTests { @@ -43,6 +47,39 @@ void insufficientPathSegments() { assertThatThrownBy(() -> testResolve(0, "/", "1.0")).isInstanceOf(InvalidApiVersionException.class); } + @Test + void excludePathTrue() { + String requestUri = "/v3/api-docs"; + testResolveWithExcludePath(requestUri, null); + } + + @Test + void excludePathFalse() { + String requestUri = "/app/1.0/path"; + testResolveWithExcludePath(requestUri, "1.0"); + } + + @Test + void excludePathFalseShortPath() { + String requestUri = "/app"; + assertThatThrownBy(() -> testResolveWithExcludePath(requestUri, null)).isInstanceOf(InvalidApiVersionException.class); + } + + private static void testResolveWithExcludePath(String requestUri, String expected) { + ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get(requestUri)); + String actual = new PathApiVersionResolver(1, requestPath -> { + List elements = requestPath.elements(); + if (elements.size() < 4) { + return false; + } + return elements.get(0).value().equals("/") && + elements.get(1).value().equals("v3") && + elements.get(2).value().equals("/") && + elements.get(3).value().equals("api-docs"); + }).resolveVersion(exchange); + assertThat(actual).isEqualTo(expected); + } + private static void testResolve(int index, String requestUri, String expected) { ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get(requestUri)); String actual = new PathApiVersionResolver(index).resolveVersion(exchange); From b4cc70bc244ca2bd8b1d6e2a3a55b5a89628bc12 Mon Sep 17 00:00:00 2001 From: Martin Mois Date: Fri, 27 Feb 2026 23:19:10 +0100 Subject: [PATCH 2/9] fix import order (checkstyle) Signed-off-by: Martin Mois --- .../web/reactive/accept/PathApiVersionResolver.java | 5 +++-- .../web/reactive/accept/PathApiVersionResolverTests.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java index 3c71446d77bf..c925567cd383 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java @@ -16,15 +16,16 @@ package org.springframework.web.reactive.accept; +import java.util.function.Predicate; + import org.jspecify.annotations.Nullable; + import org.springframework.http.server.PathContainer; import org.springframework.http.server.RequestPath; import org.springframework.util.Assert; import org.springframework.web.accept.InvalidApiVersionException; import org.springframework.web.server.ServerWebExchange; -import java.util.function.Predicate; - /** * {@link ApiVersionResolver} that extract the version from a path segment. * diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java index 437bb792903e..cdab8ff16ef1 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java @@ -16,6 +16,8 @@ package org.springframework.web.reactive.accept; +import java.util.List; + import org.junit.jupiter.api.Test; import org.springframework.http.server.PathContainer; @@ -24,8 +26,6 @@ import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest; import org.springframework.web.testfixture.server.MockServerWebExchange; -import java.util.List; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; From 12d0f3bd21e39c430401e2aba5cbd05496ada9f8 Mon Sep 17 00:00:00 2001 From: Martin Mois Date: Mon, 2 Mar 2026 19:59:47 +0100 Subject: [PATCH 3/9] restored .idea/icon.svg Signed-off-by: Martin Mois --- .idea/icon.svg | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .idea/icon.svg diff --git a/.idea/icon.svg b/.idea/icon.svg new file mode 100644 index 000000000000..89da1f709357 --- /dev/null +++ b/.idea/icon.svg @@ -0,0 +1,52 @@ + + + + +icon-framework + + + + + + From 5f070d9f47893c768032cb9bff1bf15d59112fd0 Mon Sep 17 00:00:00 2001 From: Martin Mois Date: Mon, 2 Mar 2026 20:16:22 +0100 Subject: [PATCH 4/9] #36398 includePath instead of excludePath Signed-off-by: Martin Mois --- .../accept/PathApiVersionResolver.java | 10 +++---- .../reactive/config/ApiVersionConfigurer.java | 8 +++--- .../accept/PathApiVersionResolverTests.java | 26 ++++++++++++------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java index c925567cd383..2aa0284118fe 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/PathApiVersionResolver.java @@ -41,7 +41,7 @@ public class PathApiVersionResolver implements ApiVersionResolver { private final int pathSegmentIndex; - private @Nullable Predicate excludePath = null; + private @Nullable Predicate includePath = null; /** @@ -57,11 +57,11 @@ public PathApiVersionResolver(int pathSegmentIndex) { /** * Create a resolver instance. * @param pathSegmentIndex the index of the path segment that contains the API version - * @param excludePath a {@link Predicate} that tests if the given path should be excluded + * @param includePath a {@link Predicate} that tests if the given path should be included */ - public PathApiVersionResolver(int pathSegmentIndex, Predicate excludePath) { + public PathApiVersionResolver(int pathSegmentIndex, Predicate includePath) { this(pathSegmentIndex); - this.excludePath = excludePath; + this.includePath = includePath; } @@ -69,7 +69,7 @@ public PathApiVersionResolver(int pathSegmentIndex, Predicate exclu public @Nullable String resolveVersion(ServerWebExchange exchange) { int i = 0; RequestPath path = exchange.getRequest().getPath(); - if (this.excludePath != null && this.excludePath.test(path)) { + if (this.includePath != null && !this.includePath.test(path)) { return null; } for (PathContainer.Element e : path.pathWithinApplication().elements()) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ApiVersionConfigurer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ApiVersionConfigurer.java index 1dd4a3dba6f9..51524d662c73 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ApiVersionConfigurer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ApiVersionConfigurer.java @@ -111,15 +111,15 @@ public ApiVersionConfigurer usePathSegment(int index) { /** * Add a resolver that extracts the API version from a path segment - * and that allows to exclude certain paths based on the provided {@link Predicate}. + * and that allows to include only certain paths based on the provided {@link Predicate}. *

Note that this resolver never returns {@code null}, and therefore * cannot yield to other resolvers, see {@link org.springframework.web.accept.PathApiVersionResolver}. * @param index the index of the path segment to check; e.g. for URL's like * {@code "/{version}/..."} use index 0, for {@code "/api/{version}/..."} index 1. - * @param excludePath a {@link Predicate} that allows to exclude certain paths + * @param includePath a {@link Predicate} that allows to include a certain path */ - public ApiVersionConfigurer usePathSegment(int index, Predicate excludePath) { - this.versionResolvers.add(new PathApiVersionResolver(index, excludePath)); + public ApiVersionConfigurer usePathSegment(int index, Predicate includePath) { + this.versionResolvers.add(new PathApiVersionResolver(index, includePath)); return this; } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java index cdab8ff16ef1..d75d37940e66 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/accept/PathApiVersionResolverTests.java @@ -48,24 +48,31 @@ void insufficientPathSegments() { } @Test - void excludePathTrue() { + void includePathFalse() { String requestUri = "/v3/api-docs"; - testResolveWithExcludePath(requestUri, null); + testResolveWithIncludePath(requestUri, null); } @Test - void excludePathFalse() { + void includePathTrue() { String requestUri = "/app/1.0/path"; - testResolveWithExcludePath(requestUri, "1.0"); + testResolveWithIncludePath(requestUri, "1.0"); } @Test - void excludePathFalseShortPath() { + void includePathFalseShortPath() { String requestUri = "/app"; - assertThatThrownBy(() -> testResolveWithExcludePath(requestUri, null)).isInstanceOf(InvalidApiVersionException.class); + testResolveWithIncludePath(requestUri, null); } - private static void testResolveWithExcludePath(String requestUri, String expected) { + @Test + void includePathInsufficientPathSegments() { + ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/too-short")); + assertThatThrownBy(() -> new PathApiVersionResolver(1, requestPath -> true).resolveVersion(exchange)) + .isInstanceOf(InvalidApiVersionException.class); + } + + private static void testResolveWithIncludePath(String requestUri, String expected) { ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get(requestUri)); String actual = new PathApiVersionResolver(1, requestPath -> { List elements = requestPath.elements(); @@ -73,9 +80,9 @@ private static void testResolveWithExcludePath(String requestUri, String expecte return false; } return elements.get(0).value().equals("/") && - elements.get(1).value().equals("v3") && + elements.get(1).value().equals("app") && elements.get(2).value().equals("/") && - elements.get(3).value().equals("api-docs"); + elements.get(3).value().equals("1.0"); }).resolveVersion(exchange); assertThat(actual).isEqualTo(expected); } @@ -85,5 +92,4 @@ private static void testResolve(int index, String requestUri, String expected) { String actual = new PathApiVersionResolver(index).resolveVersion(exchange); assertThat(actual).isEqualTo(expected); } - } From d8227dd2839a2b63534bd18aeaa21af877202dd8 Mon Sep 17 00:00:00 2001 From: Martin Mois Date: Mon, 2 Mar 2026 20:30:27 +0100 Subject: [PATCH 5/9] #36398 added usePathSegment(int index, Predicate includePath) in spring-webmvc Signed-off-by: Martin Mois --- .../web/accept/PathApiVersionResolver.java | 19 ++++++- .../accept/PathApiVersionResolverTests.java | 54 +++++++++++++++++++ .../annotation/ApiVersionConfigurer.java | 15 ++++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java index 9d5a93d26eee..7e381b2d2a08 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java +++ b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java @@ -16,8 +16,12 @@ package org.springframework.web.accept; +import java.util.function.Predicate; + import jakarta.servlet.http.HttpServletRequest; +import org.jspecify.annotations.Nullable; + import org.springframework.http.server.PathContainer; import org.springframework.http.server.RequestPath; import org.springframework.util.Assert; @@ -37,6 +41,7 @@ public class PathApiVersionResolver implements ApiVersionResolver { private final int pathSegmentIndex; + private @Nullable Predicate includePath; /** @@ -49,13 +54,25 @@ public PathApiVersionResolver(int pathSegmentIndex) { this.pathSegmentIndex = pathSegmentIndex; } + /** + * Create a resolver instance. + * @param pathSegmentIndex the index of the path segment that contains the API version + * @param includePath a {@link Predicate} that tests if the given path should be included + */ + public PathApiVersionResolver(int pathSegmentIndex, Predicate includePath) { + this(pathSegmentIndex); + this.includePath = includePath; + } @Override - public String resolveVersion(HttpServletRequest request) { + public @Nullable String resolveVersion(HttpServletRequest request) { if (!ServletRequestPathUtils.hasParsedRequestPath(request)) { throw new IllegalStateException("Expected parsed request path"); } RequestPath path = ServletRequestPathUtils.getParsedRequestPath(request); + if (this.includePath != null && !this.includePath.test(path)) { + return null; + } int i = 0; for (PathContainer.Element element : path.pathWithinApplication().elements()) { if (element instanceof PathContainer.PathSegment && i++ == this.pathSegmentIndex) { diff --git a/spring-web/src/test/java/org/springframework/web/accept/PathApiVersionResolverTests.java b/spring-web/src/test/java/org/springframework/web/accept/PathApiVersionResolverTests.java index 2b5c56b78d3a..cc01adcecbcb 100644 --- a/spring-web/src/test/java/org/springframework/web/accept/PathApiVersionResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/accept/PathApiVersionResolverTests.java @@ -16,8 +16,11 @@ package org.springframework.web.accept; +import java.util.List; + import org.junit.jupiter.api.Test; +import org.springframework.http.server.PathContainer; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import org.springframework.web.util.ServletRequestPathUtils; @@ -41,6 +44,57 @@ void insufficientPathSegments() { assertThatThrownBy(() -> testResolve(0, "/", "1.0")).isInstanceOf(InvalidApiVersionException.class); } + @Test + void includePathFalse() { + String requestUri = "/v3/api-docs"; + testResolveWithIncludePath(requestUri, null); + } + + @Test + void includePathTrue() { + String requestUri = "/app/1.0/path"; + testResolveWithIncludePath(requestUri, "1.0"); + } + + @Test + void includePathFalseShortPath() { + String requestUri = "/app"; + testResolveWithIncludePath(requestUri, null); + } + + @Test + void includePathInsufficientPathSegments() { + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/app"); + try { + ServletRequestPathUtils.parseAndCache(request); + assertThatThrownBy(() -> new PathApiVersionResolver(1, requestPath -> true) + .resolveVersion(request)) + .isInstanceOf(InvalidApiVersionException.class); + } finally { + ServletRequestPathUtils.clearParsedRequestPath(request); + } + } + + private static void testResolveWithIncludePath(String requestUri, String expected) { + MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri); + try { + ServletRequestPathUtils.parseAndCache(request); + String actual = new PathApiVersionResolver(1, requestPath -> { + List elements = requestPath.elements(); + if (elements.size() < 4) { + return false; + } + return elements.get(0).value().equals("/") && + elements.get(1).value().equals("app") && + elements.get(2).value().equals("/") && + elements.get(3).value().equals("1.0"); + }).resolveVersion(request); + assertThat(actual).isEqualTo(expected); + } finally { + ServletRequestPathUtils.clearParsedRequestPath(request); + } + } + private static void testResolve(int index, String requestUri, String expected) { MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri); try { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ApiVersionConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ApiVersionConfigurer.java index 92f06a09281d..46f59cc4615a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ApiVersionConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ApiVersionConfigurer.java @@ -27,6 +27,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.http.MediaType; +import org.springframework.http.server.RequestPath; import org.springframework.util.Assert; import org.springframework.web.accept.ApiVersionDeprecationHandler; import org.springframework.web.accept.ApiVersionParser; @@ -108,6 +109,20 @@ public ApiVersionConfigurer usePathSegment(int index) { return this; } + /** + * Add a resolver that extracts the API version from a path segment + * and that allows to include only certain paths based on the provided {@link Predicate}. + *

Note that this resolver never returns {@code null}, and therefore + * cannot yield to other resolvers, see {@link org.springframework.web.accept.PathApiVersionResolver}. + * @param index the index of the path segment to check; e.g. for URL's like + * {@code "/{version}/..."} use index 0, for {@code "/api/{version}/..."} index 1. + * @param includePath a {@link Predicate} that allows to include a certain path + */ + public ApiVersionConfigurer usePathSegment(int index, Predicate includePath) { + this.versionResolvers.add(new PathApiVersionResolver(index, includePath)); + return this; + } + /** * Add custom resolvers to resolve the API version. * @param resolvers the resolvers to use From f315f66f80237f38a9531bb148f32ce8493a1e7a Mon Sep 17 00:00:00 2001 From: Martin Mois Date: Mon, 2 Mar 2026 20:39:43 +0100 Subject: [PATCH 6/9] #36398 checkstyle corrections Signed-off-by: Martin Mois --- .../springframework/web/accept/PathApiVersionResolver.java | 4 ++-- .../web/accept/PathApiVersionResolverTests.java | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java index 7e381b2d2a08..91132be48065 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java +++ b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java @@ -18,10 +18,10 @@ import java.util.function.Predicate; -import jakarta.servlet.http.HttpServletRequest; - import org.jspecify.annotations.Nullable; +import jakarta.servlet.http.HttpServletRequest; + import org.springframework.http.server.PathContainer; import org.springframework.http.server.RequestPath; import org.springframework.util.Assert; diff --git a/spring-web/src/test/java/org/springframework/web/accept/PathApiVersionResolverTests.java b/spring-web/src/test/java/org/springframework/web/accept/PathApiVersionResolverTests.java index cc01adcecbcb..bd8ffa67aa2f 100644 --- a/spring-web/src/test/java/org/springframework/web/accept/PathApiVersionResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/accept/PathApiVersionResolverTests.java @@ -70,7 +70,8 @@ void includePathInsufficientPathSegments() { assertThatThrownBy(() -> new PathApiVersionResolver(1, requestPath -> true) .resolveVersion(request)) .isInstanceOf(InvalidApiVersionException.class); - } finally { + } + finally { ServletRequestPathUtils.clearParsedRequestPath(request); } } @@ -90,7 +91,8 @@ private static void testResolveWithIncludePath(String requestUri, String expecte elements.get(3).value().equals("1.0"); }).resolveVersion(request); assertThat(actual).isEqualTo(expected); - } finally { + } + finally { ServletRequestPathUtils.clearParsedRequestPath(request); } } From fa265789ea94689857e30630adb87fa55c6df6f4 Mon Sep 17 00:00:00 2001 From: Martin Mois Date: Mon, 2 Mar 2026 20:46:41 +0100 Subject: [PATCH 7/9] #36398 checkstyle corrections Signed-off-by: Martin Mois --- .../springframework/web/accept/PathApiVersionResolver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java index 91132be48065..7e381b2d2a08 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java +++ b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java @@ -18,10 +18,10 @@ import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; - import jakarta.servlet.http.HttpServletRequest; +import org.jspecify.annotations.Nullable; + import org.springframework.http.server.PathContainer; import org.springframework.http.server.RequestPath; import org.springframework.util.Assert; From d2962933910ef027fff7d5b2f92ac509f80b0bcc Mon Sep 17 00:00:00 2001 From: Martin Mois Date: Mon, 2 Mar 2026 20:54:12 +0100 Subject: [PATCH 8/9] #36398 checkstyle corrections Signed-off-by: Martin Mois --- .../springframework/web/accept/PathApiVersionResolver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java index 7e381b2d2a08..4b9b56e1ad8c 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java +++ b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java @@ -18,8 +18,6 @@ import java.util.function.Predicate; -import jakarta.servlet.http.HttpServletRequest; - import org.jspecify.annotations.Nullable; import org.springframework.http.server.PathContainer; @@ -27,6 +25,8 @@ import org.springframework.util.Assert; import org.springframework.web.util.ServletRequestPathUtils; +import jakarta.servlet.http.HttpServletRequest; + /** * {@link ApiVersionResolver} that extract the version from a path segment. * From 1b5177c3328c8c69208d79d53b9486d933f8403c Mon Sep 17 00:00:00 2001 From: Martin Mois Date: Mon, 2 Mar 2026 20:59:01 +0100 Subject: [PATCH 9/9] #36398 checkstyle corrections Signed-off-by: Martin Mois --- .../org/springframework/web/accept/PathApiVersionResolver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java index 4b9b56e1ad8c..dd21646b6560 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java +++ b/spring-web/src/main/java/org/springframework/web/accept/PathApiVersionResolver.java @@ -18,6 +18,7 @@ import java.util.function.Predicate; +import jakarta.servlet.http.HttpServletRequest; import org.jspecify.annotations.Nullable; import org.springframework.http.server.PathContainer; @@ -25,7 +26,6 @@ import org.springframework.util.Assert; import org.springframework.web.util.ServletRequestPathUtils; -import jakarta.servlet.http.HttpServletRequest; /** * {@link ApiVersionResolver} that extract the version from a path segment.