当前位置: 首页 > 知识库问答 >
问题:

无法使用webclient调用响应在映射中设置值

单于旭东
2023-03-14

在进行web客户端调用并使用前一个Mono的响应后,我无法在映射中获得填充值。以下是我所尝试的代码。parameters.size()的值为零。无法获得该值未被文件化的原因。我基本上希望从该方法返回年龄(而不是单对象)。使用block给出一个错误block()/blockfirst()/blocklast()是blocking,这在thread Reactor-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());

请建议哪里我是错误的和解决办法,以修复相同。

共有1个答案

呼延永新
2023-03-14

因为这是关于收集和使用从以前的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();
    }
}

这可以在需要时自动调用令牌endpoint来获取令牌,并直接与您首先请求的请求链接在一起。同样,这样的实现应该比处理域、错误等复杂得多。

如果您正在使用某种身份验证技术,这样的过滤器可能已经在Spring Security中以更好的方式实现了。

您可以在构建阶段在客户机上配置它,例如:

WebClient webClient = WebClient.builder().filter(new TokenFilterFunction()).build();
 类似资料:
  • 我正在尝试理解WebFlux,但在WebClient调用方面遇到了一些问题。我没有看到这一行System.out.println("CusterId="CusterId);执行它似乎不调用endpoint。但是如果我使用。订阅(客户-

  • 我从地图生成一个复选框列表。现在如何设置键的值(false/true),现在我可以在UserConfig中下载它,以便在项目的其余部分使用该值。 我的看法: 我的类UserConfig: 控制器 我不使用数据库。它只需要保存用于生成报告的值

  • 我花了一整天在谷歌,我没有看到其他人解析他们得到的响应,他们只是神奇地将它直接映射到一个完美创建的类上。我们没有这个选项,我们需要从响应体中提取accountName并将其放在AccountInformation对象中。有人知道怎么做吗?

  • 如果我用替换它,它也可以工作,那么有人能告诉我使用的好处吗? 使用编写代码: 我可以看到我们可以在中保留参数的顺序,但在我的项目中这并不重要...因此,如果订单很重要,我仍然可以使用 因此,看起来用HashMap设置一些参数根本不是一个好主意...所以我暂时删除了公认的答案,等待关于这一点的更多解释...我有合适的转换器(),我的意思是如果我使用多值地图,我就没有异常,所以HashMap就是问题所

  • 我按照这个例子运行Spring引导应用程序在库贝与重新加载配置映射。当我设置值时,一切都好。但是当我想从地图中设置null或删除值时,什么都不会发生 例如,我的初始配置映射是: 但当我将其更改为A并应用配置映射时: 然后testicek什么是字符串包含空字符串不为空,inticek什么是整数甚至没有刷新,仍然包含旧值。有什么建议可以解决这个问题吗?

  • 我在我的RecolyerView中使用了Filterable。我想做的是,从EditText中筛选recyclerview。下面是我的实际代码。 但是,在我的片段里。我无法调用Adapter.getFilter()。这里怎么了?