我正在使用 Spring Web Flux 实现一个处理程序函数,并希望提取 POST-Body 的值x-www-form-urlencoded。public Mono<ServerResponse> handle(ServerRequest incomingHttpRequest) { Mono<MultiValueMap<String, String>> formData = incomingHttpRequest.body(BodyExtractors.toFormData()); return formData .doOnEach(signal -> {LOG.info("EACH: " + signal.getType());}) .doOnSubscribe(x -> {LOG.info("SUBSCRIBED");}) .doOnNext(next -> {LOG.info("NEXT: " + next);}) .doOnError(x -> {LOG.info("ERROR: " + x.getMessage());}) .doOnSuccess(x -> {LOG.info("SUCCESS: " + x);}) .flatMap(multiValueMap -> ServerResponse .badRequest() .body(BodyInserters.fromObject( "searchTerm: " + multiValueMap.getFirst("searchTerm") )) );}处理程序添加到路由器中,如下所示:return RouterFunctions.route(RequestPredicates.POST("/mysearch"), searchHandler::handle); 我希望得到一个包含 searchTerm 的 BAD_REQUEST。但我得到的是 200。对我来说,看起来生成的 Mono 已被订阅,然后成功完成。但formData从未收到值,因此从未进入flatMap(...)我做错了什么映射Mono<MultiValueMap<String, String>>到 a Mono<ServerResponse>?
2 回答
不负相思意
TA贡献1777条经验 获得超10个赞
这里有两件事在起作用:
事实上,您只能订阅(即读取)请求正文一次
从请求中获取表单数据需要读取并解析它
在 Spring Boot 2.0.x-2.1.x 中,HiddenHttpMethodFilter
默认启用。此过滤器对于在 HTML 表单中使用浏览器本身不支持的 HTTP 方法(例如“DELETE”)非常有用。如果传入请求属于该类型,则此过滤器需要解析表单数据。
可以说,这种用例越来越少见,并且从 Spring Boot 2.2 开始默认被禁用。
现在,在您的示例中,读取和解析传入请求将不起作用,因为它已被过滤器解析。禁用过滤器可以解决该问题。
但解决这个问题的更好方法是使用专用方法request.formData()
,它将解析并缓存结果(如果多次调用,则返回已解析的数据)。
Cats萌萌
TA贡献1805条经验 获得超9个赞
每当您等待表单数据时,您应该使用
Mono<MultiValueMap<String, String>> formData = incomingHttpRequest.formData();
我已经测试过,这种和平的代码适用于这一更改。
添加回答
举报
0/150
提交
取消