如何在 Spring Boot 3 中忽略 webflux 中的尾部斜杠?

问题描述 投票:0回答:2

在 Spring Boot 3 中,它们已发生更改,默认情况下不再忽略尾部斜杠。例如,如果我有一个 GET 资源

/users
,并且导航到
/users/
,那么 Spring Boot webflux 现在将响应 404。

您可以通过实现

WebFluxConfigurer
并覆盖
configurePathMatching
方法来更改此设置:

@Override
public void configurePathMatching(PathMatchConfigurer configurer) {
     configurer.setUseTrailingSlashMatch();
}

但是,

setUseTrailingSlashMatch
已被弃用,文档说使用
PathPatternParser.setMatchOptionalTrailingSeparator(boolean)
代替。但是,我不明白您实际如何/在哪里配置它。

那么问题来了,如何设置

PathPatternParser.setMatchOptionalTrailingSeparator(boolean)

java spring-boot spring-webflux
2个回答
9
投票

正如 @joe-clay 在他的评论中提到的,

PathPatternParser.setMatchOptionalTrailingSeparator(boolean)
也已被弃用,转而支持显式重定向。所以你有 3 个选择:

  1. 在控制器处理程序中显式声明两条路由

    @GetMapping({"/users", "/users/"})
    。缺点是您需要为每个控制器执行此操作,但可以用作权宜之计。

  2. 实现

    org.springframework.web.server.WebFilter
    接口以显式重定向到所需的 url。沿着这些思路:

@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);
}
  1. 在代理中显式重写传入的 url(例如在 nginx 中使用
    rewrite
    规则)以匹配预期的 url。

在选项 2 和 3 中,您也可以选择返回

HTTP 301
响应。


0
投票

可以通过添加以下过滤器来解决此问题:

@Component
public class ServletRequestWrapperFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper((HttpServletRequest) request) {
            @Override
            public String getRequestURI() {
                String requestURI = super.getRequestURI();
                if (StringUtils.endsWith(requestURI, "/")) {
                    return StringUtils.removeEnd(requestURI, "/");
                }
                return requestURI;
            }
        };
        chain.doFilter(requestWrapper, response);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.