在进行Web客户端调用并使用上一个Mono的响应后,我无法在地图中填充值。这是我尝试的代码.parameters.size()的值变为零。能够得到为什么不填充值的原因我基本上想返回年龄(不是Mono对象) 使用block会给出一个错误block()/ blockFirst()/ blockLast()正在阻塞,这在线程反应器-http-nio-3中不支持。
Map<String, String> parameters = new HashMap<String,String>();
Mono<Person> obj = webClient
.post()
.uri("dummy url")
.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
.retrieve()
.bodyToMono(Person.class)
.flatMap(resp -> {
parameters.put("name", resp.getName());
parameters.put("age", resp.getAge());
return Mono.just(new Person(resp.getName(),resp.getAge()));
}
);
System.out.println(parameters.size());
请提出我错了的地方以及解决方法。
答案 0 :(得分:1)
由于这是关于收集和使用从先前的HTTP调用收集的某种令牌的,所以最好的选择是将所有令牌委托给ExchangeFilterFunction
。
ExchangeFilterFunction
是在客户端为每个传出请求执行的筛选器。这是这种过滤器的非常非常幼稚的实现:
class TokenFilterFunction implements ExchangeFilterFunction {
private final AtomicReference<String> token = new AtomicReference<>();
@Override
public Mono<ClientResponse> filter(ClientRequest req, ExchangeFunction next) {
if (this.token.get() == null) {
return fetchToken(next).then(sendRequest(req, next));
}
else {
return sendRequest(req, next);
}
}
private Mono<ClientResponse> sendRequest(ClientRequest req, ExchangeFunction next) {
ClientRequest request = ClientRequest.from(req)
.header("Token", this.token.get()).build();
return next.exchange(request);
}
private Mono<Void> fetchToken(ExchangeFunction next) {
ClientRequest tokenRequest = ClientRequest.create(HttpMethod.GET,
URI.create("https://example.com/token")).build();
return next.exchange(tokenRequest).doOnNext(res -> {
this.token.set(res.headers().header("Token").get(0));
}).then();
}
}
这可以自动调用令牌端点,以在需要时获取令牌,并直接与您首先提出的请求进行链接。再次,这样的实现应该比处理域,错误等复杂得多。
如果您正在使用某种身份验证技术,那么可能已经在Spring Security中以一种更好的方式实现了这种过滤器。
您可以在构建阶段在客户端上对其进行配置,例如:
WebClient webClient = WebClient.builder().filter(new TokenFilterFunction()).build();