Improve handling of empty response with Mono<T>
Issue: SPR-17560
This commit is contained in:
parent
63275ae2b7
commit
abf9ce8a34
|
@ -119,7 +119,10 @@ public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
|
|||
if (inputStream instanceof Mono) {
|
||||
HttpHeaders headers = message.getHeaders();
|
||||
return Mono.from(body)
|
||||
.defaultIfEmpty(message.bufferFactory().wrap(new byte[0]))
|
||||
.switchIfEmpty(Mono.defer(() -> {
|
||||
headers.setContentLength(0);
|
||||
return message.setComplete().then(Mono.empty());
|
||||
}))
|
||||
.flatMap(buffer -> {
|
||||
headers.setContentLength(buffer.readableByteCount());
|
||||
return message.writeWith(Mono.just(buffer));
|
||||
|
|
|
@ -34,23 +34,17 @@ import reactor.test.StepVerifier;
|
|||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.core.io.buffer.support.DataBufferTestUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.ISO_8859_1;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static java.nio.charset.StandardCharsets.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.core.ResolvableType.forClass;
|
||||
import static org.springframework.http.MediaType.TEXT_HTML;
|
||||
import static org.springframework.http.MediaType.TEXT_PLAIN;
|
||||
import static org.springframework.http.MediaType.TEXT_XML;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.core.ResolvableType.*;
|
||||
import static org.springframework.http.MediaType.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link EncoderHttpMessageWriter}.
|
||||
|
@ -174,7 +168,7 @@ public class EncoderHttpMessageWriterTests {
|
|||
public void emptyBodyWritten() {
|
||||
HttpMessageWriter<String> writer = getWriter(MimeTypeUtils.TEXT_PLAIN);
|
||||
writer.write(Mono.empty(), forClass(String.class), TEXT_PLAIN, this.response, NO_HINTS).block();
|
||||
StepVerifier.create(this.response.getBody()).expectNextCount(1).verifyComplete();
|
||||
StepVerifier.create(this.response.getBody()).expectComplete();
|
||||
assertEquals(0, this.response.getHeaders().getContentLength());
|
||||
}
|
||||
|
||||
|
|
|
@ -149,6 +149,19 @@ public class RequestMappingMessageConversionIntegrationTests extends AbstractReq
|
|||
assertEquals(expected, responseEntity.getBody());
|
||||
}
|
||||
|
||||
@Test // SPR-17506
|
||||
public void personResponseBodyWithEmptyMono() throws Exception {
|
||||
ResponseEntity<Person> responseEntity = performGet("/person-response/mono-empty", JSON, Person.class);
|
||||
assertEquals(0, responseEntity.getHeaders().getContentLength());
|
||||
assertNull(responseEntity.getBody());
|
||||
|
||||
// As we're on the same connection, the 2nd request proves server response handling
|
||||
// did complete after the 1st request..
|
||||
responseEntity = performGet("/person-response/mono-empty", JSON, Person.class);
|
||||
assertEquals(0, responseEntity.getHeaders().getContentLength());
|
||||
assertNull(responseEntity.getBody());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void personResponseBodyWithMonoDeclaredAsObject() throws Exception {
|
||||
Person expected = new Person("Robert");
|
||||
|
@ -495,6 +508,11 @@ public class RequestMappingMessageConversionIntegrationTests extends AbstractReq
|
|||
return Mono.just(new Person("Robert"));
|
||||
}
|
||||
|
||||
@GetMapping("/mono-empty")
|
||||
public Mono<Person> getMonoEmpty() {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@GetMapping("/mono-declared-as-object")
|
||||
public Object getMonoDeclaredAsObject() {
|
||||
return Mono.just(new Person("Robert"));
|
||||
|
|
Loading…
Reference in New Issue