-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Closed
Labels
in: webIssues in web modules (web, webmvc, webflux, websocket)Issues in web modules (web, webmvc, webflux, websocket)type: bugA general bugA general bug
Milestone
Description
Johannes Edmeier opened SPR-15679 and commented
When the WebClient retrieves an response without content (header content-length: 0
and without content-type
header ) I would expect following things:
- when calling exchange() and doing ClientResponse#bodyToMono(Void.class) I expect that an empty Mono (that just completes) for the body is returned
- when calling retrieve().toEntity(Void.class) I expect a Mono with a ResponseEntity instance whose hasBody() returns false.
Both is currently not possible and throws an UnsupportedMediaTypeException
Tests:
@Test
public void nocontent_entity() {
Mono<ResponseEntity<Void>> responseEntity = WebClient.create("http://localhost:8080")
.post()
.uri("/nocontent")
.retrieve()
.toEntity(Void.class);
StepVerifier.create(responseEntity).assertNext(r -> {
assertThat(r.hasBody()).isFalse();
assertThat(r.getStatusCode().is2xxSuccessful()).isTrue();
}).verifyComplete();
}
@Test
public void nocontent_response() {
Mono<ClientResponse> response = WebClient.create("http://localhost:8080").post().uri("/nocontent").exchange();
StepVerifier.create(response).assertNext(r -> {
assertThat(r.statusCode().is2xxSuccessful()).isTrue();
StepVerifier.create(r.bodyToMono(Void.class)).verifyComplete();
}).verifyComplete();
}
Application
@SpringBootApplication
@RestController
public class WebfluxApplication {
public static void main(String[] args) {
SpringApplication.run(WebfluxApplication.class, args);
}
@PostMapping(path="/nocontent")
public Mono<Void> nocontent() {
return Mono.empty();
}
}
java.lang.AssertionError: expectation "expectComplete" failed (expected: onComplete(); actual: onError(org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/octet-stream' not supported))
at reactor.test.DefaultStepVerifierBuilder.failPrefix(DefaultStepVerifierBuilder.java:2114)
at reactor.test.DefaultStepVerifierBuilder.fail(DefaultStepVerifierBuilder.java:2110)
at reactor.test.DefaultStepVerifierBuilder.lambda$expectComplete$3(DefaultStepVerifierBuilder.java:199)
at reactor.test.DefaultStepVerifierBuilder$SignalEvent.test(DefaultStepVerifierBuilder.java:1855)
at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onSignal(DefaultStepVerifierBuilder.java:1241)
at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onExpectation(DefaultStepVerifierBuilder.java:1186)
at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onError(DefaultStepVerifierBuilder.java:858)
at reactor.core.publisher.Operators.error(Operators.java:195)
at reactor.core.publisher.MonoError.subscribe(MonoError.java:51)
at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:665)
at reactor.test.DefaultStepVerifierBuilder$DefaultStepVerifier.verify(DefaultStepVerifierBuilder.java:639)
at reactor.test.DefaultStepVerifierBuilder.verifyComplete(DefaultStepVerifierBuilder.java:508)
at com.example.webflux.WebfluxApplicationTests.lambda$nocontent_response$1(WebfluxApplicationTests.java:46)
at reactor.test.DefaultStepVerifierBuilder.lambda$consumeNextWith$1(DefaultStepVerifierBuilder.java:157)
at reactor.test.DefaultStepVerifierBuilder$SignalEvent.test(DefaultStepVerifierBuilder.java:1855)
at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onSignal(DefaultStepVerifierBuilder.java:1241)
at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onExpectation(DefaultStepVerifierBuilder.java:1186)
at reactor.test.DefaultStepVerifierBuilder$DefaultVerifySubscriber.onNext(DefaultStepVerifierBuilder.java:875)
at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:108)
at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:170)
at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:108)
at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:108)
at reactor.core.publisher.FluxRetryPredicate$RetryPredicateSubscriber.onNext(FluxRetryPredicate.java:79)
at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:122)
at reactor.ipc.netty.channel.PooledClientContextHandler.fireContextActive(PooledClientContextHandler.java:84)
at reactor.ipc.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:542)
at reactor.ipc.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:125)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at java.lang.Thread.run(Thread.java:745)
Suppressed: org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/octet-stream' not supported
at org.springframework.web.reactive.function.BodyExtractors.lambda$readWithMessageReaders$16(BodyExtractors.java:237)
at java.util.Optional.orElseGet(Optional.java:267)
at org.springframework.web.reactive.function.BodyExtractors.readWithMessageReaders(BodyExtractors.java:233)
at org.springframework.web.reactive.function.BodyExtractors.lambda$toMono$1(BodyExtractors.java:92)
at org.springframework.web.reactive.function.client.DefaultClientResponse.body(DefaultClientResponse.java:78)
at org.springframework.web.reactive.function.client.DefaultClientResponse.bodyToMono(DefaultClientResponse.java:98)
... 34 more
Affects: 5.0 RC2
Issue Links:
- WebClient fails to transform empty json array to emtpy flux [SPR-15703] #20260 WebClient fails to transform empty json array to emtpy flux ("is duplicated by")
Metadata
Metadata
Assignees
Labels
in: webIssues in web modules (web, webmvc, webflux, websocket)Issues in web modules (web, webmvc, webflux, websocket)type: bugA general bugA general bug