Web上的Webflux嵌套路由器始终返回404

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web上的Webflux嵌套路由器始终返回404相关的知识,希望对你有一定的参考价值。

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

码:

    public RouterFunction<ServerResponse> productRouter(final ProductHandler handler) {
        return nest(path(apiPath + BASE_PATH),
                route(POST("/").and(contentType(MediaType.APPLICATION_JSON)), handler::handleCreateProduct)
                        .andRoute(GET("/{id}"), handler::handleGetProductById)
                        .andRoute(PUT("/").and(contentType(MediaType.APPLICATION_JSON)), handler::handleUpdateProduct)
                        .andRoute(GET("/"), handler::handleGetAllProducts)
                        .andNest(path("/category"),
                                route(POST("/").and(contentType(MediaType.APPLICATION_JSON)), handler::handleCreateProductCategory)
                                        .andRoute(GET("/{id}"), handler::handleGetProductCategoryById)
                                        .andRoute(GET("/"), handler::handleGetAllProductCategories)
                                        .andRoute(GET("/search/{name}"), handler::handleGetProductCategoriesByName)
                        ))
                .andNest(path("/brand"),
                        route(POST("/").and(contentType(MediaType.APPLICATION_JSON)), handler::handleCreateProductBrand)
                                .andRoute(GET("/"), handler::handleGetAllProductBrands)
                                .andRoute(GET("/{id}"), handler::handleGetProductBrandById));
    }

无法正常工作的路线如下:

.andRoute(GET("/"), handler::handleGetAllProductCategories)

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

谢谢你的帮助

答案

我没有设法在Spring Boot 2.1.2.RELEASE上重现此问题,具有以下内容:

@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"))));
    }
}

我得到了结果:

➜  ~ http :8080/test
HTTP/1.1 200 OK
Content-Length: 4
Content-Type: text/plain;charset=UTF-8

TEST

➜  ~ http :8080/test/
HTTP/1.1 200 OK
Content-Length: 4
Content-Type: text/plain;charset=UTF-8

TEST

➜  ~ http :8080/test/other
HTTP/1.1 200 OK
Content-Length: 5
Content-Type: text/plain;charset=UTF-8

OTHER

➜  ~ http :8080/test/other/
HTTP/1.1 200 OK
Content-Length: 5
Content-Type: text/plain;charset=UTF-8

OTHER

➜  ~ http :8080/test/other/something
HTTP/1.1 200 OK
Content-Length: 2
Content-Type: text/plain;charset=UTF-8

ID

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

另一答案

现在,Weblux中有一个关于映射根元素的开放式错误:https://github.com/spring-projects/spring-boot/issues/9785

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

另一答案

感谢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));
}

我已经将/ category和/ brand路径在链中比根路径更高,并且它按预期工作。

再次请求Brian帮忙!

以上是关于Web上的Webflux嵌套路由器始终返回404的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 webflux 中使用 WebFilter corsFilter 时请求返回 404 状态?

WebFlux 功能:如何检测空 Flux 并返回 404?

Jetty 和 Dropwizard:如何始终返回 200 而不是 404、500 等

部署时,动态网页始终返回404

Laravel 路由上的 PHPunit 测试总是返回 404

部署在 Google App Engine 上的应用的 /healthz 路由返回 404