Spring Webflux webclient 出现问题,尝试发送 post 请求时没有任何反应 [英] Issue with Spring Webflux webclient , nothing happens when trying to send post request

查看:161
本文介绍了Spring Webflux webclient 出现问题,尝试发送 post 请求时没有任何反应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有以下webclient的实现:

 public WebClient.ResponseSpec sendRequest(HttpMethod method, String contentType, T body, String baseUrl, String path) {尝试 {WebClient webClient = WebClient.builder().baseUrl(baseUrl).filter(logRequest()).build();WebClient.ResponseSpec responseSpec = webClient.method(method).uri(路径).header(HttpHeaders.CONTENT_TYPE, contentType).body(BodyInserters.fromObject(body)).取回();返回响应规范;} 捕获(异常 e){throw new WebClientProcessingException("尝试执行请求时出现异常", e);}}//此方法返回过滤器函数,该函数将记录请求数据私有静态 ExchangeFilterFunction logRequest() {返回 ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {LOGGER.info("Request: {} {} {}", clientRequest.method(), clientRequest.url(), clientRequest.body());clientRequest.headers().forEach((name, values) -> values.forEach(value -> LOGGER.info("{}={}", name, value)));返回 Mono.just(clientRequest);});}

还有下面的代码,创建用户对象和包含用户对象的命令,然后调用webclient发送请求

@Autowired私人 BaseWebClient baseWebClient;@覆盖公共无效 saveOrUpdateUser() {UserPayload userPayload = new UserPayload();userPayload.setUserId(111L);userPayload.setCreatedAt(ZonedDateTime.now(DateTimeProps.systemTimeZone));UserCommand userCommand = new UserCommand();userCommand.setUser(userPayload);baseWebClient.sendRequest(HttpMethod.POST, "application/json",Stream.of(userCommand).collect(Collectors.toList()),"http://localhost:8080","/users").onStatus(HttpStatus::isError, clientResponse -> {throw new WebClientUserSaveOrUpdateeFailedException("尝试更新用户状态时出现异常").bodyToMono(String.class);});}

用户负载:

@Data@NoArgsConstructor@AllArgsConstructor公共类 UserPayload {长用户 ID;ZonedDateTime createdAt;}

用户命令:

@Data@NoArgsConstructor@AllArgsConstructor公共类用户命令{@JsonProperty("用户")UserPayload 用户;}

Json 正在等待我的其他应用程序(我正在向其发送请求):

<预><代码>[{用户":{用户 ID":1,"createdAt": "2019-05-16T08:24:46.412Z"}}]

使用:Spring boot 2、Lombok(用于 getter/setter)、gradle当我尝试发送请求时,什么也没有发生.甚至也不例外.我尝试了非常简单的案例以及同样的问题.再注意一点,是否可以记录身体?我是说以某种方式看到最终的 json我想我错过了一些一般的东西.

解决方案

在 Reactor 中,在您订阅之前不会发生任何事情.retrive() 实际上并没有启动请求.正如您在 example,您应该使用其中一种方法将 ResponseSpec 转换为发布者,然后最终订阅该发布者.

根据您使用此方法的方式,您或许可以让 Spring 改为订阅发布者.WebFlux 支持模型中的响应式类型,这意味着您可以直接从您的 RestController 方法返回 Mono,例如例子.

Have the following implementation of webclient :

    public <T> WebClient.ResponseSpec sendRequest(HttpMethod method, String contentType, T body, String baseUrl, String path) {
    try {
        WebClient webClient = WebClient.builder().baseUrl(baseUrl).filter(logRequest()).build();
        WebClient.ResponseSpec responseSpec = webClient.method(method)
                .uri(path)
                .header(HttpHeaders.CONTENT_TYPE, contentType)
                .body(BodyInserters.fromObject(body))
                .retrieve();
        return responseSpec;
    } catch (Exception e) {
        throw new WebClientProcessingException("Exception when trying to execute request", e);

    }
}

// This method returns filter function which will log request data
private static ExchangeFilterFunction logRequest() {
    return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
        LOGGER.info("Request: {} {} {}", clientRequest.method(), clientRequest.url(), clientRequest.body());
        clientRequest.headers().forEach((name, values) -> values.forEach(value -> LOGGER.info("{}={}", name, value)));
        return Mono.just(clientRequest);
    });
}

Also have the following code , which is creating user object and command which contains user object , then calling webclient to send an request

@Autowired
private BaseWebClient baseWebClient;
@Override
public void saveOrUpdateUser() {
        UserPayload userPayload = new UserPayload();
        userPayload.setUserId(111L);
        userPayload.setCreatedAt(ZonedDateTime.now(DateTimeProps.systemTimeZone));
        UserCommand userCommand = new UserCommand();
        userCommand.setUser(userPayload);
        baseWebClient.sendRequest(HttpMethod.POST, "application/json",
            Stream.of(userCommand).collect(Collectors.toList()),
            "http://localhost:8080",
            "/users").onStatus(HttpStatus::isError, clientResponse -> {
        throw new WebClientUserSaveOrUpdateeFailedException("Exception when trying to update user state")
        .bodyToMono(String.class);
    });
}

User payload :

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserPayload {
  Long userId;
  ZonedDateTime createdAt;
}

User command :

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserCommand {
     @JsonProperty("user")
     UserPayload user;
}

Json which is waiting for my other app (whom I am sending a request) :

[
  { "user":
            { 
              "userId": 1,
              "createdAt": "2019-05-16T08:24:46.412Z"
            } 
  }
]

Using : Spring boot 2 , Lombok (for getter/setter) , gradle When I'm trying to send a request nothing happens. No exception even. I tried with very simple case as well the same issue. One more note, is it possible to log body? I mean somehow see final json I guess I am missing something general.

解决方案

In Reactor, nothing happens until you subscribe. retrive() does not actually start the request. As you can see in the example, you should use one of the method to convert the ResponseSpec to a Publisher and then eventually subscribe to that publisher.

Depending on how you're using this method, you might be able to let Spring subscribe to the publisher instead. WebFlux supports reactive types in the model which means you can directly return a Mono from your RestController methods, for example.

这篇关于Spring Webflux webclient 出现问题,尝试发送 post 请求时没有任何反应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆