From 8c3fc8c549f29c5c5e4ddca43bdf4c7b7e1c0311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Tue, 13 Feb 2024 13:20:29 +0100 Subject: [PATCH] Add documentation for functional resource handling Closes gh-27257 --- .../ROOT/pages/web/webflux-functional.adoc | 67 +++++++++++++++++++ .../ROOT/pages/web/webmvc-functional.adoc | 67 +++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc index 35a5b50588..b56f90d37a 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux-functional.adoc @@ -782,6 +782,73 @@ Kotlin:: ====== +[[webflux-fn-serving-resources]] +== Serving Resources + +WebFlux.fn provides built-in support for serving resources. + +NOTE: In addition to the capabilities described below, it is possible to implement an even more flexible resource handling thanks to +{spring-framework-api}++/web/reactive/function/server/RouterFunctions.html#resources(java.util.function.Function)++[`RouterFunctions#resource(java.util.function.Function)`]. + +[[webflux-fn-resource]] +=== Redirecting to a resource + +It is possible to redirect requests matching a specified predicate to a resource. This can be useful, for example, +for handling redirects in Single Page Applications. + +[tabs] +====== +Java:: ++ +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +---- +ClassPathResource index = new ClassPathResource("static/index.html"); +List extensions = List.of("js", "css", "ico", "png", "jpg", "gif"); +RequestPredicate spaPredicate = path("/api/**").or(path("/error")).or(pathExtension(extensions::contains)).negate(); +RouterFunction redirectToIndex = route() + .resource(spaPredicate, index) + .build(); +---- + +Kotlin:: ++ +[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] +---- +val redirectToIndex = router { + val index = ClassPathResource("static/index.html") + val extensions = listOf("js", "css", "ico", "png", "jpg", "gif") + val spaPredicate = !(path("/api/**") or path("/error") or + pathExtension(extensions::contains)) + resource(spaPredicate, index) +} +---- +====== + +[[webflux-fn-resources]] +=== Serving resources from a root location + +It is also possible to route requests that match a given pattern to resources relative to a given root location. + +[tabs] +====== +Java:: ++ +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +---- +Resource location = new FileSystemResource("public-resources/"); +RouterFunction resources = RouterFunctions.resources("/resources/**", location); +---- + +Kotlin:: ++ +[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] +---- +val location = FileSystemResource("public-resources/") +val resources = router { resources("/resources/**", location) } +---- +====== + + [[webflux-fn-running]] == Running a Server [.small]#xref:web/webmvc-functional.adoc#webmvc-fn-running[See equivalent in the Servlet stack]# diff --git a/framework-docs/modules/ROOT/pages/web/webmvc-functional.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-functional.adoc index 8d146310be..c68a41e6d1 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc-functional.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc-functional.adoc @@ -760,6 +760,73 @@ Kotlin:: ====== +[[webmvc-fn-serving-resources]] +== Serving Resources + +WebMvc.fn provides built-in support for serving resources. + +NOTE: In addition to the capabilities described below, it is possible to implement an even more flexible resource handling thanks to +{spring-framework-api}++/web/servlet/function/RouterFunctions.html#resources(java.util.function.Function)++[`RouterFunctions#resource(java.util.function.Function)`]. + +[[webmvc-fn-resource]] +=== Redirecting to a resource + +It is possible to redirect requests matching a specified predicate to a resource. This can be useful, for example, +for handling redirects in Single Page Applications. + +[tabs] +====== +Java:: ++ +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +---- +ClassPathResource index = new ClassPathResource("static/index.html"); +List extensions = List.of("js", "css", "ico", "png", "jpg", "gif"); +RequestPredicate spaPredicate = path("/api/**").or(path("/error")).or(pathExtension(extensions::contains)).negate(); +RouterFunction redirectToIndex = route() + .resource(spaPredicate, index) + .build(); +---- + +Kotlin:: ++ +[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] +---- +val redirectToIndex = router { + val index = ClassPathResource("static/index.html") + val extensions = listOf("js", "css", "ico", "png", "jpg", "gif") + val spaPredicate = !(path("/api/**") or path("/error") or + pathExtension(extensions::contains)) + resource(spaPredicate, index) +} +---- +====== + +[[webmvc-fn-resources]] +=== Serving resources from a root location + +It is also possible to route requests that match a given pattern to resources relative to a given root location. + +[tabs] +====== +Java:: ++ +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +---- +Resource location = new FileSystemResource("public-resources/"); +RouterFunction resources = RouterFunctions.resources("/resources/**", location); +---- + +Kotlin:: ++ +[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] +---- +val location = FileSystemResource("public-resources/") +val resources = router { resources("/resources/**", location) } +---- +====== + + [[webmvc-fn-running]] == Running a Server [.small]#xref:web/webflux-functional.adoc#webflux-fn-running[See equivalent in the Reactive stack]#