Spring WebFlux,提取请求体

Posted

技术标签:

【中文标题】Spring WebFlux,提取请求体【英文标题】:Spring WebFlux, extracting the request body 【发布时间】:2020-10-17 06:11:40 【问题描述】:

我正在编写一个小型 WebFlux 客户端代理,它将接受 POST 请求,提取 JSON 内容,然后通过另一个 POST 将其传递给第三方 Web 服务器的进一步调用。我想在我的原始 POST 请求中获取 json 正文。

curl --header "Content-Type: application/json" \
  --request POST \
  --data '"username":"xyz", "preference":"123"' \
  http://localhost:3000/mih/search

这是我处理上述 POST 的路线:

@Bean
open fun route(searchService: SearchService): RouterFunction<ServerResponse> 
    return RouterFunctions.route(
            RequestPredicates.POST("/search").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),
            HandlerFunction 
                    request: ServerRequest -> searchService.search(request.body(BodyExtractors.toMono(String::class.java)))
             )
    
open class SearchService(private val myWebClient: MyWebClient): ISearchService 

    override fun search(json: String): Mono<ServerResponse> 
        return myWebClient.myPost(json)
    

import org.springframework.web.reactive.function.client.WebClient

open class MyWebClient(
    private val springWebClient: WebClient,
    private val properties: properties ) : IMyWebClient 

    override fun myPost(json: String): Mono<ServerResponse> 
        return springWebClient.post()
            .uri("/base/queries", properties.getBase)
            .body(
                BodyInserters.fromPublisher(Mono.just(json), String::class.java)
            ).retrieve().bodyToMono(
                ServerResponse::class.java
            )
    

当我转到 .subscribe()Mono&lt;String&gt; 时,我得到了

Type mismatch.
  Required: String
  Found: Disposable

如何成功提取请求正文?

【问题讨论】:

WebClient.post(json) 之前没见过那个函数,在 api 声明中也找不到。您需要调用exchangeretreive 来执行请求,然后获取响应并提取正文并将其映射到某物。更多关于 WebClient 的用法可以阅读官方文档docs.spring.io/spring/docs/current/spring-framework-reference/… @MeanwhileInHell - 我认为您应该在 webClient 上调用 bodyToMono&lt;String&gt;,然后将字符串包装到 ServerResponse 的新对象中 【参考方案1】:

根据文档: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient.html#post--

post() 返回 WebClient.RequestBodyUriSpec 而不是 ServerResponse

您对 API 的使用不正确。您应该在search() 方法调用之后使用.retrieve()

在您的情况下,.body() 应用于 POST 请求正文。

您应该继续:

.search().retrieve().bodyToMono(String.class)

【讨论】:

抱歉,我的问题应该更简洁。我从 WebClient 的呼叫中呼叫 retreive()。我已编辑我的答案以包含我自己的网络客户端代码和扩展背景信息。 不过,您不能调用.bodyToMono(ServerResponse::class.java) 并期望它自动变成响应,您可以做的是调用bodyToMono&lt;String&gt;() 然后map 返回ServerResponse。 Reactor 不知道如何将某种字符串映射到ServerResponse,也不知道要返回哪个状态码...

以上是关于Spring WebFlux,提取请求体的主要内容,如果未能解决你的问题,请参考以下文章

Spring-webflux 过滤器获取请求正文

Spring Boot 简单的请求示例(包括请求体验证)

在spring mvc测试中访问请求体和请求头

如何在不阻塞的情况下从 Spring Webflux 中的 Mono 对象中提取数据?

spring rest 处理空请求体(400 Bad Request)

spring boot aop打印http请求回复日志包含请求体