Document UrlHandler Servlet and reactive filters
Closes gh-33784
This commit is contained in:
parent
3cc76ef87c
commit
acccbbec3f
|
|
@ -419,6 +419,24 @@ controllers. However, when you use it with Spring Security, we advise relying on
|
|||
|
||||
See the section on xref:web/webflux-cors.adoc[CORS] and the xref:web/webflux-cors.adoc#webflux-cors-webfilter[CORS `WebFilter`] for more details.
|
||||
|
||||
[[filters.url-handler]]
|
||||
=== URL Handler
|
||||
[.small]#xref:web/webmvc/filters.adoc#filters.url-handler[See equivalent in the Servlet stack]#
|
||||
|
||||
You may want your controller endpoints to match routes with or without a trailing slash in the URL path.
|
||||
For example, both "GET /home" and "GET /home/" should be handled by a controller method annotated with `@GetMapping("/home")`.
|
||||
|
||||
Adding trailing slash variants to all mapping declarations is not the best way to handle this use case.
|
||||
The `UrlHandlerFilter` web filter has been designed for this purpose. It can be configured to:
|
||||
|
||||
* respond with an HTTP redirect status when receiving URLs with trailing slashes, sending browsers to the non-trailing slash URL variant.
|
||||
* mutate the request to act as if the request was sent without a trailing slash and continue the processing of the request.
|
||||
|
||||
Here is how you can instantiate and configure a `UrlHandlerFilter` for a blog application:
|
||||
|
||||
include-code::./UrlHandlerFilterConfiguration[tag=config,indent=0]
|
||||
|
||||
|
||||
|
||||
[[webflux-exception-handler]]
|
||||
== Exceptions
|
||||
|
|
|
|||
|
|
@ -9,7 +9,11 @@ The `spring-web` module provides some useful filters:
|
|||
* xref:web/webmvc/filters.adoc#filters-forwarded-headers[Forwarded Headers]
|
||||
* xref:web/webmvc/filters.adoc#filters-shallow-etag[Shallow ETag]
|
||||
* xref:web/webmvc/filters.adoc#filters-cors[CORS]
|
||||
* xref:web/webmvc/filters.adoc#filters.url-handler[URL Handler]
|
||||
|
||||
Servlet filters can be configured in the `web.xml` configuration file or using Servlet annotations.
|
||||
If you are using Spring Boot, you can
|
||||
{spring-boot-docs}/how-to/webserver.html#howto.webserver.add-servlet-filter-listener.spring-bean[declare them as beans and configure them as part of your application].
|
||||
|
||||
|
||||
[[filters-http-put]]
|
||||
|
|
@ -109,4 +113,22 @@ See the sections on xref:web/webmvc-cors.adoc[CORS] and the xref:web/webmvc-cors
|
|||
|
||||
|
||||
|
||||
[[filters.url-handler]]
|
||||
== URL Handler
|
||||
[.small]#xref:web/webflux/reactive-spring.adoc#filters.url-handler[See equivalent in the Reactive stack]#
|
||||
|
||||
In previous Spring Framework versions, Spring MVC could be configured to ignore trailing slashes in URL paths
|
||||
when mapping incoming requests on controller methods. This could be done by enabling the `setUseTrailingSlashMatch`
|
||||
option on the `PathMatchConfigurer`. This means that sending a "GET /home/" request would be handled by a controller
|
||||
method annotated with `@GetMapping("/home")`.
|
||||
|
||||
This option has been retired, but applications are still expected to handle such requests in a safe way.
|
||||
The `UrlHandlerFilter` Servlet filter has been designed for this purpose. It can be configured to:
|
||||
|
||||
* respond with an HTTP redirect status when receiving URLs with trailing slashes, sending browsers to the non-trailing slash URL variant.
|
||||
* wrap the request to act as if the request was sent without a trailing slash and continue the processing of the request.
|
||||
|
||||
Here is how you can instantiate and configure a `UrlHandlerFilter` for a blog application:
|
||||
|
||||
include-code::./UrlHandlerFilterConfiguration[tag=config,indent=0]
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2002-2024 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.docs.web.webflux.filters.urlhandler;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.filter.reactive.UrlHandlerFilter;
|
||||
|
||||
public class UrlHandlerFilterConfiguration {
|
||||
|
||||
public void configureUrlHandlerFilter() {
|
||||
// tag::config[]
|
||||
UrlHandlerFilter urlHandlerFilter = UrlHandlerFilter
|
||||
// will HTTP 308 redirect "/blog/my-blog-post/" -> "/blog/my-blog-post"
|
||||
.trailingSlashHandler("/blog/**").redirect(HttpStatus.PERMANENT_REDIRECT)
|
||||
// will mutate the request to "/admin/user/account/" and make it as "/admin/user/account"
|
||||
.trailingSlashHandler("/admin/**").mutateRequest()
|
||||
.build();
|
||||
// end::config[]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2002-2024 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.docs.web.webmvc.filters.urlhandler;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.filter.UrlHandlerFilter;
|
||||
|
||||
public class UrlHandlerFilterConfiguration {
|
||||
|
||||
public void configureUrlHandlerFilter() {
|
||||
// tag::config[]
|
||||
UrlHandlerFilter urlHandlerFilter = UrlHandlerFilter
|
||||
// will HTTP 308 redirect "/blog/my-blog-post/" -> "/blog/my-blog-post"
|
||||
.trailingSlashHandler("/blog/**").redirect(HttpStatus.PERMANENT_REDIRECT)
|
||||
// will wrap the request to "/admin/user/account/" and make it as "/admin/user/account"
|
||||
.trailingSlashHandler("/admin/**").wrapRequest()
|
||||
.build();
|
||||
// end::config[]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2002-2024 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.docs.web.webflux.filters.urlhandler
|
||||
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.web.filter.reactive.UrlHandlerFilter
|
||||
|
||||
class UrlHandlerFilterConfiguration {
|
||||
|
||||
fun configureUrlHandlerFilter() {
|
||||
// tag::config[]
|
||||
val urlHandlerFilter = UrlHandlerFilter
|
||||
// will HTTP 308 redirect "/blog/my-blog-post/" -> "/blog/my-blog-post"
|
||||
.trailingSlashHandler("/blog/**").redirect(HttpStatus.PERMANENT_REDIRECT)
|
||||
// will mutate the request to "/admin/user/account/" and make it as "/admin/user/account"
|
||||
.trailingSlashHandler("/admin/**").mutateRequest()
|
||||
.build()
|
||||
// end::config[]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2002-2024 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.docs.web.webmvc.filters.urlhandler
|
||||
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.web.filter.UrlHandlerFilter
|
||||
|
||||
class UrlHandlerFilterConfiguration {
|
||||
|
||||
fun configureUrlHandlerFilter() {
|
||||
// tag::config[]
|
||||
val urlHandlerFilter = UrlHandlerFilter
|
||||
// will HTTP 308 redirect "/blog/my-blog-post/" -> "/blog/my-blog-post"
|
||||
.trailingSlashHandler("/blog/**").redirect(HttpStatus.PERMANENT_REDIRECT)
|
||||
// will wrap the request to "/admin/user/account/" and make it as "/admin/user/account"
|
||||
.trailingSlashHandler("/admin/**").wrapRequest()
|
||||
.build()
|
||||
// end::config[]
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue