Spring 根目录上的Webflux嵌套路由器始终返回404

Spring 根目录上的Webflux嵌套路由器始终返回404,spring,spring-boot,spring-webflux,Spring,Spring Boot,Spring Webflux,我有一个RouterFunction,里面有嵌套的路由,除了一条路由之外的所有东西都在使用,我认为它们应该这样做 但是当我试图调用嵌套路由中的一个根路由时,我总是得到404。这只发生在特定路由上,当我将其从root更改为“/foo”时,它开始工作。 代码: 奇怪的是,在根路径和品牌路径下,我做了完全相同的事情,这些路径工作 感谢您的帮助现在Weblux中有一个关于映射根元素的开放性错误: 您应该使用重定向或不使用“/”映射。现在Weblux中有一个关于映射根元素的公开错误: 您应该使用重定向或不

我有一个RouterFunction,里面有嵌套的路由,除了一条路由之外的所有东西都在使用,我认为它们应该这样做
但是当我试图调用嵌套路由中的一个根路由时,我总是得到404。这只发生在特定路由上,当我将其从root更改为“/foo”时,它开始工作。

代码:

奇怪的是,在根路径和品牌路径下,我做了完全相同的事情,这些路径工作


感谢您的帮助

现在Weblux中有一个关于映射根元素的开放性错误:


您应该使用重定向或不使用“/”映射。

现在Weblux中有一个关于映射根元素的公开错误:


您应该使用重定向或不使用“/”映射。

我没有在Spring Boot 2.1.2.RELEASE上重现此问题,原因如下:

.andRoute(GET("/"), handler::handleGetAllProductCategories)
@Configuration
public class RouterConfig {

    @Bean
    public RouterFunction<ServerResponse> productRouter() {
        return nest(path("/test"),
                route(GET("/"), serverRequest -> ServerResponse.ok().syncBody("TEST"))
                        .andNest(path("/other"),
                                route(GET("/{id}"), serverRequest -> ServerResponse.ok().syncBody("ID"))
                                .andRoute(GET("/"), serverRequest -> ServerResponse.ok().syncBody("OTHER"))));
    }
}

如果您设法在示例应用程序中重现此问题,请在上创建一个问题,因为我没有找到该问题的现有问题。请提供一个示例项目,我们可以克隆并运行该项目来重现问题。

我没有在Spring Boot 2.1.2.RELEASE上重现此问题,原因如下:

.andRoute(GET("/"), handler::handleGetAllProductCategories)
@Configuration
public class RouterConfig {

    @Bean
    public RouterFunction<ServerResponse> productRouter() {
        return nest(path("/test"),
                route(GET("/"), serverRequest -> ServerResponse.ok().syncBody("TEST"))
                        .andNest(path("/other"),
                                route(GET("/{id}"), serverRequest -> ServerResponse.ok().syncBody("ID"))
                                .andRoute(GET("/"), serverRequest -> ServerResponse.ok().syncBody("OTHER"))));
    }
}

如果您设法在示例应用程序中重现此问题,请在上创建一个问题,因为我没有找到该问题的现有问题。请在那里提供一个示例项目,我们可以克隆并运行该项目来重现问题。

多亏了Brian Clozel的评论,我才能够解决这个问题

keep in mind that router functions are about the first route that matches.
因此,考虑到这一点,我以以下方式重新构建了我的RouterFunction:

public RouterFunction<ServerResponse> productRouter(final ProductHandler handler) {

        return nest(path(apiPath + BASE_PATH),
                route(method(HttpMethod.POST).and(accept(MediaType.MULTIPART_FORM_DATA)), handler::handleCreateProduct)
                        .andNest(path("/category"),
                                route(GET("/{id}"), handler::handleGetProductCategoryById)
                                        .andRoute(method(HttpMethod.POST).and(contentType(MediaType.APPLICATION_JSON)), handler::handleCreateProductCategory)
                                        .andRoute(GET("/search/{name}"), handler::handleGetProductCategoriesByName)
                                        .andRoute(method(HttpMethod.GET), handler::handleGetAllProductCategories))
                        .andNest(path("/brand"),
                                route(method(HttpMethod.POST).and(contentType(MediaType.APPLICATION_JSON)), handler::handleCreateProductBrand)
                                        .andRoute(GET("/{id}"), handler::handleGetProductBrandById)
                                        .andRoute(method(HttpMethod.GET), handler::handleGetAllProductBrands))
                        .andRoute(GET("/{id}/pdf"), handler::handlaProductDetailsPdf)
                        .andRoute(GET("/{id}"), handler::handleGetProductById)
                        .andRoute(method(HttpMethod.PUT).and(contentType(MediaType.APPLICATION_JSON)), handler::handleUpdateProduct)
                        .andRoute(method(HttpMethod.GET), handler::handleGetAllProducts));
}
publicRouterFunction产品路由器(最终产品处理程序){
返回嵌套(路径(apiPath+BASE_路径),
路由(方法(HttpMethod.POST)和(接受(MediaType.MULTIPART\u FORM\u DATA)),handleCreateProduct)
.andNest(路径(“/category”),
路由(GET(“/{id}”),处理程序::handleGetProductCategoryById)
.andRoute(方法(HttpMethod.POST)和(contentType(MediaType.APPLICATION_JSON)),handleCreateProductCategory)
.andRoute(GET(“/search/{name}”),handleGetProductCategoriesByName)
.andRoute(方法(HttpMethod.GET),处理程序::handleGetAllProductCategories))
.andNest(路径(“/品牌”),
路由(方法(HttpMethod.POST)和(contentType(MediaType.APPLICATION_JSON)),handleCreateProductBrand)
.andRoute(GET(“/{id}”),handleGetProductBrandById)
.andRoute(方法(HttpMethod.GET),handler::handleGetAllProductBrands))
.andRoute(GET(“/{id}/pdf”),handler::handlaProductDetailsPdf)
.andRoute(GET(“/{id}”),handleGetProductById)
.andRoute(方法(HttpMethod.PUT)和(contentType(MediaType.APPLICATION_JSON)),handleUpdateProduct)
.andRoute(方法(HttpMethod.GET),handler::handleGetAllProducts);
}
我已经将/category和/brand路径在链中移动到比根路径更高的位置,并且它按照预期工作


再次感谢布莱恩的帮助

多亏了布赖恩·克洛泽尔的评论,我才明白了这一点

keep in mind that router functions are about the first route that matches.
因此,考虑到这一点,我以以下方式重新构建了我的RouterFunction:

public RouterFunction<ServerResponse> productRouter(final ProductHandler handler) {

        return nest(path(apiPath + BASE_PATH),
                route(method(HttpMethod.POST).and(accept(MediaType.MULTIPART_FORM_DATA)), handler::handleCreateProduct)
                        .andNest(path("/category"),
                                route(GET("/{id}"), handler::handleGetProductCategoryById)
                                        .andRoute(method(HttpMethod.POST).and(contentType(MediaType.APPLICATION_JSON)), handler::handleCreateProductCategory)
                                        .andRoute(GET("/search/{name}"), handler::handleGetProductCategoriesByName)
                                        .andRoute(method(HttpMethod.GET), handler::handleGetAllProductCategories))
                        .andNest(path("/brand"),
                                route(method(HttpMethod.POST).and(contentType(MediaType.APPLICATION_JSON)), handler::handleCreateProductBrand)
                                        .andRoute(GET("/{id}"), handler::handleGetProductBrandById)
                                        .andRoute(method(HttpMethod.GET), handler::handleGetAllProductBrands))
                        .andRoute(GET("/{id}/pdf"), handler::handlaProductDetailsPdf)
                        .andRoute(GET("/{id}"), handler::handleGetProductById)
                        .andRoute(method(HttpMethod.PUT).and(contentType(MediaType.APPLICATION_JSON)), handler::handleUpdateProduct)
                        .andRoute(method(HttpMethod.GET), handler::handleGetAllProducts));
}
publicRouterFunction产品路由器(最终产品处理程序){
返回嵌套(路径(apiPath+BASE_路径),
路由(方法(HttpMethod.POST)和(接受(MediaType.MULTIPART\u FORM\u DATA)),handleCreateProduct)
.andNest(路径(“/category”),
路由(GET(“/{id}”),处理程序::handleGetProductCategoryById)
.andRoute(方法(HttpMethod.POST)和(contentType(MediaType.APPLICATION_JSON)),handleCreateProductCategory)
.andRoute(GET(“/search/{name}”),handleGetProductCategoriesByName)
.andRoute(方法(HttpMethod.GET),处理程序::handleGetAllProductCategories))
.andNest(路径(“/品牌”),
路由(方法(HttpMethod.POST)和(contentType(MediaType.APPLICATION_JSON)),handleCreateProductBrand)
.andRoute(GET(“/{id}”),handleGetProductBrandById)
.andRoute(方法(HttpMethod.GET),handler::handleGetAllProductBrands))
.andRoute(GET(“/{id}/pdf”),handler::handlaProductDetailsPdf)
.andRoute(GET(“/{id}”),handleGetProductById)
.andRoute(方法(HttpMethod.PUT)和(contentType(MediaType.APPLICATION_JSON)),handleUpdateProduct)
.andRoute(方法(HttpMethod.GET),handler::handleGetAllProducts);
}
我已经将/category和/brand路径在链中移动到比根路径更高的位置,并且它按照预期工作


再次感谢布莱恩的帮助

这是另一个问题;您所指的问题是关于在SpringBoot中支持欢迎页面的支持。在本例中,OP尝试匹配嵌套路径下的路由。是的,您是对的。我最近面对它,我想它会应用于基根映射,这是一个不同的问题;您所指的问题是关于在SpringBoot中支持欢迎页面的支持。在本例中,OP尝试匹配嵌套路径下的路由。是的,您是对的。我最近遇到了这个问题,我想它会应用于基本根映射,你能提供更多信息吗?
apiPath
BASE\u PATH
的值是什么?apiPath=“/api/v1”和BASE\u PATH=“/products”s