[英]Spring webclient throws “Only one connection receive subscriber allowed” when response does not contain media type header
[英]"IllegalStateException: Only one connection receive subscriber allowed" when response body is empty
我有一个 Spring Boot 2.3.1 项目,我在其中使用 WebClient 调用远程服务。
远程服务不是很可靠,往往会返回 500 错误,有无响应体。 我的目标是抛出一个包含响应正文(或默认消息)的自定义异常,以便我可以记录它,这是我的代码:
webClient.get()
.uri(targetServiceUri)
.retrieve()
.onStatus(HttpStatus::is5xxServerError, clientResponse ->
clientResponse.bodyToMono(String.class)
.flatMap(error ->
Mono.error(new MyCustomServiceException(error))
)
)
.toEntity(String.class)
.block();
我使用wiremock进行了2个测试,第一个有效:
@Test
void shouldThrowCustomExceptionWhenServiceReturns500ServerErrorWithNoBody() {
setStubForInValidCheckCall(HttpStatus.INTERNAL_SERVER_ERROR,"{'Error':'invalid request'}");
Throwable thrown =
catchThrowable(() -> myClient.performComplianceCheck(getCompany()));
assertThat(thrown)
.isInstanceOf(MyCustomServiceException.class)
.hasMessageContaining("{'Error':'invalid request'}");
}
private void setStubForInValidCheckCall(HttpStatus httpStatus, String body) {
var response= aResponse().withStatus(httpStatus.value());
if(body!=null){
response=response.withBody(body);
}
stubFor(
get(urlPathMatching("/targetCompliance"))
.willReturn(response));
}
但是,响应为 500 但没有正文(或者如果它是空字符串)的第二个测试失败并显示"java.lang.IllegalStateException: Only one connection receive subscriber allowed.
@Test
void shouldThrowCustomExceptionWhenServiceReturns500ServerErrorWithNoBody() {
setStubForInValidCheckCall(HttpStatus.INTERNAL_SERVER_ERROR,null);
Throwable thrown =
catchThrowable(() -> myClient.performComplianceCheck(getCompany()));
assertThat(thrown)
.isInstanceOf(MyCustomServiceException.class)
.hasMessageContaining("service returned status 500");
}
我正在努力理解为什么会发生这种情况,以及如何解决它..
是“正常的”吗? 还是我遗漏了一些明显的东西(我的测试有问题吗?)?
我找到了一种解决方法,但它根本感觉不到“webFlux-y”,而且我仍然不明白为什么会发生Only one connection receive subscriber allowed
:
try {
ResponseEntity<String> responseEntity =
webClient.get()
.uri(targetServiceUri)
.retrieve()
.toEntity(String.class)
.block();
}
catch (WebClientException e) {
if(e instanceof InternalServerError){
var internalServerError=(InternalServerError) e;
if(internalServerError.getStatusCode().is5xxServerError()){
var respBody=internalServerError.getResponseBodyAsString();
if(StringUtils.isEmpty(respBody)){
respBody=MY_STANDARD_MESSAGE +internalServerError.getRawStatusCode() ;
}
throw new MyCustomServiceException(respBody);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.