Spring WebClient - 错误底层 HTTP 客户端已完成但未发出响应

use*_*453 9 java spring-boot spring-rest

我有一个 spring boot(版本 2.1.8.RELEASE)rest 应用程序,其中包含来自控制器的以下邮件功能:

@PostMapping(value = "/sendMail1")
public  @ResponseBody EmailResponse sendMail1( @RequestBody EmailRequestDto emailRequestDto) {


        if (checkAllEmailAddValid(emailRequestDto)) {
            sendMailService.sendEmail(emailRequestDto);
            //return new ResponseEntity<>("Mail has been sent successfully", HttpStatus.OK);

            return new EmailResponse(HttpStatus.OK, "Mail has been sent successfully");
        } else {
            LOG.error("Email addresse provided is  invalid");
            //return new ResponseEntity<>("Email address provided is  invalid", HttpStatus.BAD_REQUEST);

            return new EmailResponse(HttpStatus.BAD_REQUEST, "Email address provided is  invalid");
        }

    }
Run Code Online (Sandbox Code Playgroud)

为服务类发送邮件的方法是:

@Override
    @Async("threadPoolExecutor")
    public void sendEmail(EmailRequestDto emailRequestDto) {




        LOG.debug("calling method sendMail");

        ...

        }
Run Code Online (Sandbox Code Playgroud)

我已在我的计算机上部署了上述其余服务,并可通过 url( http://localhost:9090/email-service/email/sendMail1 ) 进行访问。但是,当我使用 Spring WebClient 调用 Web 服务时,会显示以下错误,并且根本不调用 Web 服务:

java.lang.IllegalStateException: The underlying HTTP client completed without emitting a response
Run Code Online (Sandbox Code Playgroud)

请在下面找到我调用网络服务的集成测试:

@Test
public void test() {

EmailRequestDto emailRequestDto = new EmailRequestDto();
emailRequestDto.setMailTo((Arrays.asList("dummy@hotmail.com")));
emailRequestDto.setEmailContent("Dear Sir");
emailRequestDto.setMailFrom("dummy12@hotmail.com");
emailRequestDto.setSubject("Sending Email subject - 17102019-0905");

emailRequestDto.setFileHtml(true);

WebClient webClient = WebClient
          .builder()
            .baseUrl("http://localhost:9090/email-service/email")
                        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)   
          .build();



Mono <EmailResponse>  rs = webClient.post().uri("/sendMail1").body(Mono.just(emailRequestDto), EmailRequestDto.class).retrieve().bodyToMono(EmailResponse.class);


System.out.println(rs);
Run Code Online (Sandbox Code Playgroud)

}

当我使用 Postman 客户端插件执行相同的功能时,Web 服务被成功调用。

知道我在这里缺少什么吗?

Tii*_*ina 1

使用WebClient,logRequest和进行调试时logResponse非常有帮助。最有可能的是,从电子邮件服务器返回非 2xx 状态代码。

public static ExchangeFilterFunction logResponse() {
    return ExchangeFilterFunction.ofResponseProcessor(response -> {
        logStatus(response);
        logHeaders(response);

        return logBody(response);
    });
}
Run Code Online (Sandbox Code Playgroud)

logStatus都很logHeader简单,因为人们可以轻松地从 获取该信息responselogBody是棘手的一个:

private static Mono<ClientResponse> logBody(ClientResponse response) {
    if ((response.statusCode().is4xxClientError() || response.statusCode().is5xxServerError())) {
        return response.bodyToMono(String.class)
                .defaultIfEmpty(response.statusCode().getReasonPhrase()) response"
                .flatMap(body -> {
                    log.info("Body is {}", body);
                    return Mono.just(response);
                });
    } else {
        return Mono.just(response);
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,defaultIfEmpty没有主体的响应需要,这在响应代码为非 2xx 时很常见。否则你会得到类似的错误IllegalStateException The underlying HTTP client completed without emitting a response。原因可能如中所述