WebClient 5.3+ 交换与 exchangeToMono。一起提取 cookie 和 body
Posted
技术标签:
【中文标题】WebClient 5.3+ 交换与 exchangeToMono。一起提取 cookie 和 body【英文标题】:WebClient 5.3+ exchange vs exchangeToMono. Extracting cookies and body together 【发布时间】:2021-03-20 11:05:40 【问题描述】:我目前正在尝试使用通过 webClient 返回的整个请求。我需要能够阅读它附带的 body 和 cookies。但是,我目前在一个电话中同时处理这两个问题。下面我有两种方法来获取我想要的数据。我对使用 lambdas 和 webClient 很陌生。我确实意识到 exchangeToMono() 是返回 Mono 或 Flux 的最新方法调用,因为在 exchange() 中可能存在内存泄漏。 我想说订阅()返回 monoBody 可能对我有帮助,但到目前为止,我也没有运气以这种方式提取数据。谢谢大家的意见。
Mono<String> monoBody = webBuilder.build()
.get()
.uri(baseURI + "?Level=&pageSize=50&pageNo=&name=&id=&authToken=" + sessionToken)
.accept(MediaType.ALL)
.header("authToken", sessionToken)
.header("x-Token", sessionToken)
.header("X-token-X", sessionToken)
.header("Ref", ref)
.exchangeToMono(clientResponse -> clientResponse.bodyToMono(String.class));
Mono<MultiValueMap<String,ResponseCookie>> monoMap = webBuilder.build()
.get()
.uri(baseURI + "?Level=&pageSize=50&pageNo=&unitName=&id=&authToken=" + sessionToken)
.accept(MediaType.ALL)
.header("authToken", sessionToken)
.header("x-Token", sessionToken)
.header("X-token-X", sessionToken)
.header("Ref", ref)
.exchangeToMono(clientResponse -> Mono.fromCallable(()-> clientResponse.cookies() ));
【问题讨论】:
【参考方案1】:关于 Reactor API(由 WebClient 使用)要记住的关键是您始终将操作组合成一个“计划”,然后在某个时间点(订阅)执行整个计划。
在您的情况下,您已经找到了两种获取所需信息的方法,但是对于 Reactive 流,您只能在流中的任何点拥有一种类型,因此如果您需要两种类型的数据,您可以随时将它们组合成一个复合对象。
record DataWithCookies(MultiValueMap<String,ResponseCookie> cookies, String body)
...
Mono<DataWithCookies> dataWithCookies =
webBuilder.build()
.get()
.uri(baseURI + "?Level=&pageSize=50&pageNo=&unitName=&id=&authToken=" + sessionToken)
.accept(MediaType.ALL)
.header("authToken", sessionToken)
.header("x-Token", sessionToken)
.header("X-token-X", sessionToken)
.header("Ref", ref)
.exchangeToMono(response ->
response.bodyToMono(String.class)
.map(stringBody -> new DataWithCookies(
stringBody,
response.cookies())
)
);
我使用了previewed JDK 16 feature "Records" for brevity,但您可以为DataWithCookies
使用一个简单的类。
您现在有了一个 Mono ,它将产生主体和 cookie。您甚至可能想将该 lambda 提取到一个私有方法中以提高可读性。
...
.exchangeToMono(this::extractBodyAndCookies);
...
private DataWithCookies extractBodyAndCookies(final ClientResponse response)
return response.bodyToMono(String.class)
.map(stringBody -> new DataWithCookies(stringBody,
response.cookies())
);
另一种选择是使用Tuples.of(stringBody, response.cookies())
,这样可以避免创建另一种类型,同时仍然组合两个数据。
【讨论】:
谢谢,这种数据装箱帮助了。我希望有一个比这种方式更简单的选择,但我现在猜测,这必须是它的完成方式。感谢您抽出宝贵时间回复。以上是关于WebClient 5.3+ 交换与 exchangeToMono。一起提取 cookie 和 body的主要内容,如果未能解决你的问题,请参考以下文章
思科模拟器Packet tracert 5.3 我想用1 PC连接一交换机或者路由器,怎么启动超级终端,
如何将 WebClient 与 .Net Core 一起使用?