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<String>
时,我得到了
Type mismatch.
Required: String
Found: Disposable
如何成功提取请求正文?
【问题讨论】:
WebClient.post(json)
之前没见过那个函数,在 api 声明中也找不到。您需要调用exchange
或retreive
来执行请求,然后获取响应并提取正文并将其映射到某物。更多关于 WebClient 的用法可以阅读官方文档docs.spring.io/spring/docs/current/spring-framework-reference/…
@MeanwhileInHell - 我认为您应该在 webClient 上调用 bodyToMono<String>
,然后将字符串包装到 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<String>()
然后map
返回ServerResponse
。 Reactor 不知道如何将某种字符串映射到ServerResponse
,也不知道要返回哪个状态码...以上是关于Spring WebFlux,提取请求体的主要内容,如果未能解决你的问题,请参考以下文章
如何在不阻塞的情况下从 Spring Webflux 中的 Mono 对象中提取数据?