Вложенный маршрутизатор Webflux в корне всегда возвращает 404 - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть RouterFunction с вложенными маршрутами, все, кроме одного маршрута, с которым я думаю, что они должны делать.Но когда я пытаюсь вызвать один из корневых маршрутов внутри вложенного маршрута, я всегда получаю 404. Это происходит только с этим конкретным маршрутом, и когда я меняю его с корневого на "/ 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)

Странная вещь заключается в корневом пути и пути брендов.точно так же и эти маршруты работают.

Спасибо за помощь

Ответы [ 3 ]

0 голосов
/ 09 февраля 2019

Мне не удалось воспроизвести эту проблему в 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 , поскольку мне не удалось найти существующую проблему для этого.Пожалуйста, предоставьте пример проекта, который мы можем клонировать и запустить, чтобы воспроизвести проблему.

0 голосов
/ 13 февраля 2019

Благодаря комментарию Брайана Клозела я смог разобраться в этом

keep in mind that router functions are about the first route that matches.

Итак, помня об этом, я перестроил свои функции Router следующим образом:

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 выше в цепочке, чем корневой путь, и он работает, как и ожидалось.

Снова спасибо Брайану за помощь!

0 голосов
/ 09 февраля 2019

Сейчас в Weblux есть открытая ошибка, связанная с отображением корневого элемента: https://github.com/spring-projects/spring-boot/issues/9785

Вы должны либо использовать перенаправление, либо не использовать отображение "/".

...