In Spring Boot 3, they have changed so that trailing slashes, by default, are no longer ignored. For example, if I have a GET resource, /users
, and I navigate to /users/
then Spring Boot webflux will now respond with 404.
You can change this by implementing a WebFluxConfigurer
and overriding the configurePathMatching
method:
@Override
public void configurePathMatching(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch();
}
However, setUseTrailingSlashMatch
is deprecated, and the docs says to use PathPatternParser.setMatchOptionalTrailingSeparator(boolean)
instead. However, I don't understand how/where you actually configure this.
So the question is, how do I set PathPatternParser.setMatchOptionalTrailingSeparator(boolean)
?
As @joe-clay has mentioned in his comment, PathPatternParser.setMatchOptionalTrailingSeparator(boolean)
is deprecated as well in favour of explicit redirects. So you have 3 options:
Declare both routes explicitly in the controller handler @GetMapping({"/users", "/users/"})
. The downside is that you need to do this for every controller, but can be used as a stop-gap solution.
Implement org.springframework.web.server.WebFilter
interface to explicitly redirect to the desired url. Something along these lines:
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
URI originalUri = exchange.getRequest().getURI();
if (/* check condition for trailing slash using originalUri getPath(), getQuery() etc. */) {
String originalPath = originalUri.getPath();
String newPath = originalPath.substring(0, originalPath.length() - 1); // ignore trailing slash
try {
URI newUri = new URI(originalUri.getScheme(),
originalUri.getUserInfo(),
originalUri.getHost(),
originalUri.getPort(),
newPath,
originalUri.getQuery(),
originalUri.getFragment());
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.MOVED_PERMANENTLY); // optional
response.getHeaders().setLocation(mutatedUri);
return Mono.empty();
} catch (URISyntaxException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
return chain.filter(exchange);
}
rewrite
rules in nginx) to match the expected url.In options 2 and 3, you may choose to return an HTTP 301
response as well.