Skip to content

Commit 41a9db3

Browse files
committedDec 19, 2024
Deprecate pathExtension routing predicates
Closes gh-34103
1 parent 62d9600 commit 41a9db3

File tree

16 files changed

+108
-17
lines changed

16 files changed

+108
-17
lines changed
 

‎framework-docs/modules/ROOT/pages/web/webflux-functional.adoc

+2-5
Original file line numberDiff line numberDiff line change
@@ -803,8 +803,7 @@ Java::
803803
[source,java,indent=0,subs="verbatim,quotes"]
804804
----
805805
ClassPathResource index = new ClassPathResource("static/index.html");
806-
List<String> extensions = List.of("js", "css", "ico", "png", "jpg", "gif");
807-
RequestPredicate spaPredicate = path("/api/**").or(path("/error")).or(pathExtension(extensions::contains)).negate();
806+
RequestPredicate spaPredicate = path("/api/**").or(path("/error")).negate();
808807
RouterFunction<ServerResponse> redirectToIndex = route()
809808
.resource(spaPredicate, index)
810809
.build();
@@ -816,9 +815,7 @@ Kotlin::
816815
----
817816
val redirectToIndex = router {
818817
val index = ClassPathResource("static/index.html")
819-
val extensions = listOf("js", "css", "ico", "png", "jpg", "gif")
820-
val spaPredicate = !(path("/api/**") or path("/error") or
821-
pathExtension(extensions::contains))
818+
val spaPredicate = !(path("/api/**") or path("/error"))
822819
resource(spaPredicate, index)
823820
}
824821
----

‎framework-docs/modules/ROOT/pages/web/webmvc-functional.adoc

+2-4
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ Java::
782782
----
783783
ClassPathResource index = new ClassPathResource("static/index.html");
784784
List<String> extensions = List.of("js", "css", "ico", "png", "jpg", "gif");
785-
RequestPredicate spaPredicate = path("/api/**").or(path("/error")).or(pathExtension(extensions::contains)).negate();
785+
RequestPredicate spaPredicate = path("/api/**").or(path("/error")).negate();
786786
RouterFunction<ServerResponse> redirectToIndex = route()
787787
.resource(spaPredicate, index)
788788
.build();
@@ -794,9 +794,7 @@ Kotlin::
794794
----
795795
val redirectToIndex = router {
796796
val index = ClassPathResource("static/index.html")
797-
val extensions = listOf("js", "css", "ico", "png", "jpg", "gif")
798-
val spaPredicate = !(path("/api/**") or path("/error") or
799-
pathExtension(extensions::contains))
797+
val spaPredicate = !(path("/api/**") or path("/error"))
800798
resource(spaPredicate, index)
801799
}
802800
----

‎spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java

+16
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,12 @@ public static RequestPredicate OPTIONS(String pattern) {
270270
* Return a {@code RequestPredicate} that matches if the request's path has the given extension.
271271
* @param extension the path extension to match against, ignoring case
272272
* @return a predicate that matches if the request's path has the given file extension
273+
* @deprecated without replacement to discourage use of path extensions for request
274+
* mapping and for content negotiation (with similar deprecations and removals already
275+
* applied to annotated controllers). For further context, please read issue
276+
* <a href="https://github.com/spring-projects/spring-framework/issues/24179">#24179</a>
273277
*/
278+
@Deprecated(since = "7.0", forRemoval = true)
274279
public static RequestPredicate pathExtension(String extension) {
275280
Assert.notNull(extension, "'extension' must not be null");
276281
return new PathExtensionPredicate(extension);
@@ -282,7 +287,12 @@ public static RequestPredicate pathExtension(String extension) {
282287
* @param extensionPredicate the predicate to test against the request path extension
283288
* @return a predicate that matches if the given predicate matches against the request's path
284289
* file extension
290+
* @deprecated without replacement to discourage use of path extensions for request
291+
* mapping and for content negotiation (with similar deprecations and removals already
292+
* applied to annotated controllers). For further context, please read issue
293+
* <a href="https://github.com/spring-projects/spring-framework/issues/24179">#24179</a>
285294
*/
295+
@Deprecated(since = "7.0", forRemoval = true)
286296
public static RequestPredicate pathExtension(Predicate<String> extensionPredicate) {
287297
return new PathExtensionPredicate(extensionPredicate);
288298
}
@@ -354,7 +364,12 @@ public interface Visitor {
354364
* Receive notification of a path extension predicate.
355365
* @param extension the path extension that makes up the predicate
356366
* @see RequestPredicates#pathExtension(String)
367+
* @deprecated without replacement to discourage use of path extensions for request
368+
* mapping and for content negotiation (with similar deprecations and removals already
369+
* applied to annotated controllers). For further context, please read issue
370+
* <a href="https://github.com/spring-projects/spring-framework/issues/24179">#24179</a>
357371
*/
372+
@Deprecated(since = "7.0", forRemoval = true)
358373
void pathExtension(String extension);
359374

360375
/**
@@ -816,6 +831,7 @@ public String toString() {
816831
}
817832

818833

834+
@Deprecated(since = "7.0", forRemoval = true)
819835
private static class PathExtensionPredicate implements RequestPredicate {
820836

821837
private final Predicate<String> extensionPredicate;

‎spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ToStringVisitor.java

+2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ public void path(String pattern) {
102102
this.builder.append(pattern);
103103
}
104104

105+
@SuppressWarnings("removal")
106+
@Deprecated(since = "7.0", forRemoval = true)
105107
@Override
106108
public void pathExtension(String extension) {
107109
this.builder.append(String.format("*.%s", extension));

‎spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/CoRouterFunctionDsl.kt

+20-1
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,11 @@ class CoRouterFunctionDsl internal constructor (private val init: (CoRouterFunct
507507
* Route to the given handler function if the given pathExtension predicate applies.
508508
* @see RouterFunctions.route
509509
*/
510+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
511+
"content negotiation (with similar deprecations and removals already applied to" +
512+
"annotated controllers). For further context, please read issue " +
513+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
514+
@Suppress("removal", "DEPRECATION")
510515
fun pathExtension(extension: String, f: suspend (ServerRequest) -> ServerResponse) {
511516
builder.add(RouterFunctions.route(RequestPredicates.pathExtension(extension), asHandlerFunction(f)))
512517
}
@@ -516,21 +521,35 @@ class CoRouterFunctionDsl internal constructor (private val init: (CoRouterFunct
516521
* @param extension the path extension to match against, ignoring case
517522
* @return a predicate that matches if the request's path has the given file extension
518523
*/
524+
@Suppress("removal", "DEPRECATION")
525+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
526+
"content negotiation (with similar deprecations and removals already applied to" +
527+
"annotated controllers). For further context, please read issue " +
528+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
519529
fun pathExtension(extension: String): RequestPredicate = RequestPredicates.pathExtension(extension)
520530

521531
/**
522532
* Route to the given handler function if the given pathExtension predicate applies.
523533
* @see RouterFunctions.route
524534
*/
535+
@Suppress("removal", "DEPRECATION")
536+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
537+
"content negotiation (with similar deprecations and removals already applied to" +
538+
"annotated controllers). For further context, please read issue " +
539+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
525540
fun pathExtension(predicate: (String?) -> Boolean, f: suspend (ServerRequest) -> ServerResponse) {
526541
builder.add(RouterFunctions.route(RequestPredicates.pathExtension(predicate), asHandlerFunction(f)))
527542
}
528543

529544
/**
530545
* Return a [RequestPredicate] that matches if the request's path matches the given
531546
* predicate.
532-
* @see RequestPredicates.pathExtension
533547
*/
548+
@Suppress("removal", "DEPRECATION")
549+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
550+
"content negotiation (with similar deprecations and removals already applied to" +
551+
"annotated controllers). For further context, please read issue " +
552+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
534553
fun pathExtension(predicate: (String?) -> Boolean): RequestPredicate =
535554
RequestPredicates.pathExtension(predicate)
536555

‎spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDsl.kt

+20-1
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,11 @@ class RouterFunctionDsl internal constructor (private val init: RouterFunctionDs
554554
* Route to the given handler function if the given pathExtension predicate applies.
555555
* @see RouterFunctions.route
556556
*/
557+
@Suppress("removal", "DEPRECATION")
558+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
559+
"content negotiation (with similar deprecations and removals already applied to" +
560+
"annotated controllers). For further context, please read issue " +
561+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
557562
fun pathExtension(extension: String, f: (ServerRequest) -> Mono<out ServerResponse>) {
558563
builder.add(RouterFunctions.route(RequestPredicates.pathExtension(extension)) { f(it).cast(ServerResponse::class.java) })
559564
}
@@ -563,21 +568,35 @@ class RouterFunctionDsl internal constructor (private val init: RouterFunctionDs
563568
* @param extension the path extension to match against, ignoring case
564569
* @return a predicate that matches if the request's path has the given file extension
565570
*/
571+
@Suppress("removal", "DEPRECATION")
572+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
573+
"content negotiation (with similar deprecations and removals already applied to" +
574+
"annotated controllers). For further context, please read issue " +
575+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
566576
fun pathExtension(extension: String): RequestPredicate = RequestPredicates.pathExtension(extension)
567577

568578
/**
569579
* Route to the given handler function if the given pathExtension predicate applies.
570580
* @see RouterFunctions.route
571581
*/
582+
@Suppress("removal", "DEPRECATION")
583+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
584+
"content negotiation (with similar deprecations and removals already applied to" +
585+
"annotated controllers). For further context, please read issue " +
586+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
572587
fun pathExtension(predicate: (String?) -> Boolean, f: (ServerRequest) -> Mono<out ServerResponse>) {
573588
builder.add(RouterFunctions.route(RequestPredicates.pathExtension(predicate)) { f(it).cast(ServerResponse::class.java) })
574589
}
575590

576591
/**
577592
* Return a [RequestPredicate] that matches if the request's path matches the given
578593
* predicate.
579-
* @see RequestPredicates.pathExtension
580594
*/
595+
@Suppress("removal", "DEPRECATION")
596+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
597+
"content negotiation (with similar deprecations and removals already applied to" +
598+
"annotated controllers). For further context, please read issue " +
599+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
581600
fun pathExtension(predicate: (String?) -> Boolean): RequestPredicate =
582601
RequestPredicates.pathExtension(predicate)
583602

‎spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RequestPredicatesTests.java

+2
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ void multipleAccepts() {
296296
assertThat(predicate.test(request)).isFalse();
297297
}
298298

299+
@SuppressWarnings("removal")
299300
@Test
300301
void pathExtension() {
301302
RequestPredicate predicate = RequestPredicates.pathExtension("txt");
@@ -319,6 +320,7 @@ void pathExtension() {
319320
assertThat(predicate.test(request)).isFalse();
320321
}
321322

323+
@SuppressWarnings("removal")
322324
@Test
323325
void pathExtensionPredicate() {
324326
List<String> extensions = List.of("foo", "bar");

‎spring-webflux/src/test/java/org/springframework/web/reactive/function/server/ToStringVisitorTests.java

-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import static org.springframework.web.reactive.function.server.RequestPredicates.method;
3030
import static org.springframework.web.reactive.function.server.RequestPredicates.methods;
3131
import static org.springframework.web.reactive.function.server.RequestPredicates.path;
32-
import static org.springframework.web.reactive.function.server.RequestPredicates.pathExtension;
3332
import static org.springframework.web.reactive.function.server.RequestPredicates.queryParam;
3433
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
3534

@@ -69,8 +68,6 @@ void predicates() {
6968

7069
testPredicate(path("/foo"), "/foo");
7170

72-
testPredicate(pathExtension("foo"), "*.foo");
73-
7471
testPredicate(contentType(MediaType.APPLICATION_JSON), "Content-Type: application/json");
7572

7673
ToStringVisitor visitor = new ToStringVisitor();

‎spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/CoRouterFunctionDslTests.kt

+1
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ class CoRouterFunctionDslTests {
333333
null
334334
}
335335
}
336+
@Suppress("DEPRECATION")
336337
GET(pathExtension { it == "properties" }) {
337338
ok().bodyValueAndAwait("foo=bar")
338339
}

‎spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/RouterFunctionDslTests.kt

+1
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ class RouterFunctionDslTests {
265265
Mono.empty()
266266
}
267267
}
268+
@Suppress("DEPRECATION")
268269
GET(pathExtension { it == "properties" }) {
269270
ok().bodyValue("foo=bar")
270271
}

‎spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java

+16
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,12 @@ public static RequestPredicate OPTIONS(String pattern) {
269269
* Return a {@code RequestPredicate} that matches if the request's path has the given extension.
270270
* @param extension the path extension to match against, ignoring case
271271
* @return a predicate that matches if the request's path has the given file extension
272+
* @deprecated without replacement to discourage use of path extensions for request
273+
* mapping and for content negotiation (with similar deprecations and removals already
274+
* applied to annotated controllers). For further context, please read issue
275+
* <a href="https://github.com/spring-projects/spring-framework/issues/24179">#24179</a>
272276
*/
277+
@Deprecated(since = "7.0", forRemoval = true)
273278
public static RequestPredicate pathExtension(String extension) {
274279
Assert.notNull(extension, "'extension' must not be null");
275280
return new PathExtensionPredicate(extension);
@@ -281,7 +286,12 @@ public static RequestPredicate pathExtension(String extension) {
281286
* @param extensionPredicate the predicate to test against the request path extension
282287
* @return a predicate that matches if the given predicate matches against the request's path
283288
* file extension
289+
* @deprecated without replacement to discourage use of path extensions for request
290+
* mapping and for content negotiation (with similar deprecations and removals already
291+
* applied to annotated controllers). For further context, please read issue
292+
* <a href="https://github.com/spring-projects/spring-framework/issues/24179">#24179</a>
284293
*/
294+
@Deprecated(since = "7.0", forRemoval = true)
285295
public static RequestPredicate pathExtension(Predicate<String> extensionPredicate) {
286296
return new PathExtensionPredicate(extensionPredicate);
287297
}
@@ -352,7 +362,12 @@ public interface Visitor {
352362
* Receive notification of a path extension predicate.
353363
* @param extension the path extension that makes up the predicate
354364
* @see RequestPredicates#pathExtension(String)
365+
* @deprecated without replacement to discourage use of path extensions for request
366+
* mapping and for content negotiation (with similar deprecations and removals already
367+
* applied to annotated controllers). For further context, please read issue
368+
* <a href="https://github.com/spring-projects/spring-framework/issues/24179">#24179</a>
355369
*/
370+
@Deprecated(since = "7.0", forRemoval = true)
356371
void pathExtension(String extension);
357372

358373
/**
@@ -814,6 +829,7 @@ public String toString() {
814829
}
815830

816831

832+
@Deprecated(since = "7.0", forRemoval = true)
817833
private static class PathExtensionPredicate implements RequestPredicate {
818834

819835
private final Predicate<String> extensionPredicate;

‎spring-webmvc/src/main/java/org/springframework/web/servlet/function/ToStringVisitor.java

+2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ public void path(String pattern) {
101101
this.builder.append(pattern);
102102
}
103103

104+
@SuppressWarnings("removal")
105+
@Deprecated(since = "7.0", forRemoval = true)
104106
@Override
105107
public void pathExtension(String extension) {
106108
this.builder.append(String.format("*.%s", extension));

‎spring-webmvc/src/main/kotlin/org/springframework/web/servlet/function/RouterFunctionDsl.kt

+20
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,11 @@ class RouterFunctionDsl internal constructor (private val init: (RouterFunctionD
549549
* Route to the given handler function if the given pathExtension predicate applies.
550550
* @see RouterFunctions.route
551551
*/
552+
@Suppress("removal", "DEPRECATION")
553+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
554+
"content negotiation (with similar deprecations and removals already applied to" +
555+
"annotated controllers). For further context, please read issue " +
556+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
552557
fun pathExtension(extension: String, f: (ServerRequest) -> ServerResponse) {
553558
builder.add(RouterFunctions.route(RequestPredicates.pathExtension(extension), HandlerFunction(f)))
554559
}
@@ -558,12 +563,22 @@ class RouterFunctionDsl internal constructor (private val init: (RouterFunctionD
558563
* @param extension the path extension to match against, ignoring case
559564
* @return a predicate that matches if the request's path has the given file extension
560565
*/
566+
@Suppress("removal", "DEPRECATION")
567+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
568+
"content negotiation (with similar deprecations and removals already applied to" +
569+
"annotated controllers). For further context, please read issue " +
570+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
561571
fun pathExtension(extension: String): RequestPredicate = RequestPredicates.pathExtension(extension)
562572

563573
/**
564574
* Route to the given handler function if the given pathExtension predicate applies.
565575
* @see RouterFunctions.route
566576
*/
577+
@Suppress("removal", "DEPRECATION")
578+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
579+
"content negotiation (with similar deprecations and removals already applied to" +
580+
"annotated controllers). For further context, please read issue " +
581+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
567582
fun pathExtension(predicate: (String?) -> Boolean, f: (ServerRequest) -> ServerResponse) {
568583
builder.add(RouterFunctions.route(RequestPredicates.pathExtension(predicate), HandlerFunction(f)))
569584
}
@@ -573,6 +588,11 @@ class RouterFunctionDsl internal constructor (private val init: (RouterFunctionD
573588
* predicate.
574589
* @see RequestPredicates.pathExtension
575590
*/
591+
@Suppress("removal", "DEPRECATION")
592+
@Deprecated("without replacement to discourage use of path extensions for request mapping and for" +
593+
"content negotiation (with similar deprecations and removals already applied to" +
594+
"annotated controllers). For further context, please read issue " +
595+
"https://github.com/spring-projects/spring-framework/issues/24179", replaceWith = ReplaceWith("None"))
576596
fun pathExtension(predicate: (String?) -> Boolean): RequestPredicate =
577597
RequestPredicates.pathExtension(predicate)
578598

‎spring-webmvc/src/test/java/org/springframework/web/servlet/function/RequestPredicatesTests.java

+2
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ void multipleAccepts() {
223223
assertThat(predicate.test(request)).isFalse();
224224
}
225225

226+
@SuppressWarnings("removal")
226227
@Test
227228
void pathExtension() {
228229
RequestPredicate predicate = RequestPredicates.pathExtension("txt");
@@ -237,6 +238,7 @@ void pathExtension() {
237238
assertThat(predicate.test(initRequest("GET", "/file"))).isFalse();
238239
}
239240

241+
@SuppressWarnings("removal")
240242
@Test
241243
void pathExtensionPredicate() {
242244
List<String> extensions = List.of("foo", "bar");

‎spring-webmvc/src/test/java/org/springframework/web/servlet/function/ToStringVisitorTests.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import static org.springframework.web.servlet.function.RequestPredicates.methods;
3030
import static org.springframework.web.servlet.function.RequestPredicates.param;
3131
import static org.springframework.web.servlet.function.RequestPredicates.path;
32-
import static org.springframework.web.servlet.function.RequestPredicates.pathExtension;
3332
import static org.springframework.web.servlet.function.RouterFunctions.route;
3433

3534
/**
@@ -61,15 +60,14 @@ void nested() {
6160
assertThat(result).isEqualTo(expected);
6261
}
6362

63+
@SuppressWarnings("removal")
6464
@Test
6565
void predicates() {
6666
testPredicate(methods(HttpMethod.GET), "GET");
6767
testPredicate(methods(HttpMethod.GET, HttpMethod.POST), "[GET, POST]");
6868

6969
testPredicate(path("/foo"), "/foo");
7070

71-
testPredicate(pathExtension("foo"), "*.foo");
72-
7371
testPredicate(contentType(MediaType.APPLICATION_JSON), "Content-Type: application/json");
7472

7573
ToStringVisitor visitor = new ToStringVisitor();

‎spring-webmvc/src/test/kotlin/org/springframework/web/servlet/function/RouterFunctionDslTests.kt

+1
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ class RouterFunctionDslTests {
192192
null
193193
}
194194
}
195+
@Suppress("DEPRECATION")
195196
GET(pathExtension { it == "properties" }) {
196197
ok().body("foo=bar")
197198
}

0 commit comments

Comments
 (0)
Please sign in to comment.