繁体   English   中英

将html表单数据提交到webflux HandlerFunction

[英]Submit html form data to webflux HandlerFunction

我有一个html表单向HandlerFunction提交请求。 但是我收到错误消息,“发生意外错误(类型=不支持的媒体类型,状态= 415)。bodyType = com.reactive.ui.component不支持内容类型'application / x-www-form-urlencoded'。 SEARCHQUERY

这是表格。

<form
            action="#"
            th:action="@{/search}"
            th:object="${searchQuery}"
            method="post">
            <table>
                <tr>
                    <td>traveling from</td>
                    <td><input
                        type="text"
                        th:field="*{origin}" /></td>
                </tr>
                <tr>
                    <td>going to</td>
                    <td><input
                        type="text"
                        th:field="*{destination}" /></td>
                </tr>
                <tr>
                    <td>planning on</td>
                    <td><input
                        type="text"
                        th:field="*{flightDate}" /></td>
                </tr>
                <tr>
                    <td></td>
                    <td><input
                        type="submit"
                        value="Submit" /></td>
                </tr>
            </table>
        </form>

这是HandlerFunction。

public HandlerFunction<ServerResponse> postSearch = request ->
    {
        Mono<SearchQuery>         sq      = request.bodyToMono(SearchQuery.class);
        Flux<Flight>              flights = this.searchClient.post()
                .uri("/search/get/")
                .body(BodyInserters.fromPublisher(sq,
                                                  SearchQuery.class))
                .retrieve()
                .bodyToFlux(Flight.class);
        Map<String, Flux<Flight>> model   = new HashMap<>();
        model.put("flights",
                  flights);

        return ServerResponse.ok()
                .render("result",
                        model);
    };

这是路线。

@Bean
    RouterFunction<ServerResponse> search()
    {
        RouterFunction<ServerResponse> searchRoutes = RouterFunctions.route(GET("/"),
                                                                            uiHandler.search)
                .andRoute(POST("/search"),
                          uiHandler.postSearch);
        return searchRoutes;

    }

在这种情况下应该怎么办? 我看到了像这样的代码Mono<MultiValueMap<String, String> map = request.body(BodyExtractors.toFormData()); 但我不知道如何使用它。

我想我在解决方案附近。 这是我写的代码。 但是现在我得到“只允许一个连接接收订阅者”。 我要去哪里错了?

public HandlerFunction<ServerResponse> postSearch = request ->
    {

        return request.body(BodyExtractors.toFormData())
                .map(value ->
                {
                    sq.setOrigin(value.getFirst("origin"));
                    sq.setDestination(value.getFirst("destination"));
                    sq.setFlightDate(value.getFirst("flightDate"));
                    System.out.println(sq);
                    Flux<Flight>      flights = this.searchClient.post()
                            .uri("/search/get/")
                            .body(BodyInserters.fromObject(sq))
                            .retrieve()
                            .bodyToFlux(Flight.class);
                    Map<String, Flux<Flight>> model = new HashMap<>();
                    model.put("flights",
                              flights);
                    return model;
                })
                .flatMap(model -> ServerResponse.ok()
                        .render("result",
                                model));

    };

最后我明白了。 一直以来,我一直在使用request.body(BodyExtractors.toFormData()),上帝知道原因!但是,仅需要request.formData()。 将代码粘贴到此处使某人受益。 一点解释。 request.formData()返回Mono<MultiValueMap<String, String>> 首先,我将其映射以根据通过POST提交的值创建SearchQuery实例,然后在我调用另一个微服务以获取Flux<Flight>地方进行flatMap,然后将其放入java.util.Map中并返回ServerResponse。 实际上,您可以在单个flatMap中完成此操作,而不是先进行映射再进行flatMapping。

public HandlerFunction<ServerResponse> postSearch = request ->
    {
        return request.formData()
                .map(value ->
                {
                    SearchQuery sq = new SearchQuery();
                    sq.setOrigin(value.getFirst("origin"));
                    sq.setDestination(value.getFirst("destination"));
                    sq.setFlightDate(value.getFirst("flightDate"));
                    return sq;
                })
                .flatMap(sq ->
                {
                    Flux<Flight>      flights = this.searchClient.post()
                            .uri("/search/get/")
                            .body(BodyInserters.fromObject(sq))
                            .retrieve()
                            .bodyToFlux(Flight.class);
                    Map<String, Flux<Flight>> model = new HashMap<>();
                    model.put("flights",
                              flights);
                    return ServerResponse.ok()
                            .render("result",
                                    model);
                });

    };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM