Spring Webflux webclient 出现问题,尝试发送 post 请求时没有任何反应

nai*_*avs 5 java spring spring-boot project-reactor spring-webflux

有 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);
    });
}
Run Code Online (Sandbox Code Playgroud)

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

@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);
    });
}
Run Code Online (Sandbox Code Playgroud)

用户有效载荷:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserPayload {
  Long userId;
  ZonedDateTime createdAt;
}
Run Code Online (Sandbox Code Playgroud)

用户命令:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserCommand {
     @JsonProperty("user")
     UserPayload user;
}
Run Code Online (Sandbox Code Playgroud)

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

[
  { "user":
            { 
              "userId": 1,
              "createdAt": "2019-05-16T08:24:46.412Z"
            } 
  }
]
Run Code Online (Sandbox Code Playgroud)

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

Pan*_*nda 8

在 Reactor 中,除非您订阅否则不会发生任何事情retrive()实际上并没有启动请求。正如您在示例中看到的,您应该使用其中一种方法将 ResponseSpec 转换为发布者,然后最终订阅该发布者。

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