From e5158d47e08e9edc68db6b2b59162b33c5819e26 Mon Sep 17 00:00:00 2001 From: soldierkam Date: Wed, 28 Sep 2016 22:27:55 +0200 Subject: [PATCH] EncoderHttpMessageWriter tries to send wildcard type in response header --- .../http/codec/EncoderHttpMessageWriter.java | 6 +- .../codec/EncoderHttpMessageWriterTest.java | 55 +++++++++++++++++++ .../codec/ResourceHttpMessageWriterTests.java | 21 +------ .../ResourceRegionHttpMessageWriterTests.java | 22 +------- .../reactive/test/MockServerHttpResponse.java | 16 ++++++ 5 files changed, 80 insertions(+), 40 deletions(-) create mode 100644 spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTest.java diff --git a/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java index 8c6f20c9cd0..358944e2a51 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java @@ -110,13 +110,15 @@ public class EncoderHttpMessageWriter implements HttpMessageWriter { * Used when {@link #write} is called without a concrete content type. * *

By default returns the first of {@link Encoder#getEncodableMimeTypes() - * encodableMimeTypes}, if any. + * encodableMimeTypes} that is concrete({@link MediaType#isConcrete()}), if any. * * @param elementType the type of element for encoding * @return the content type, or {@code null} */ protected MediaType getDefaultContentType(ResolvableType elementType) { - return (!this.writableMediaTypes.isEmpty() ? this.writableMediaTypes.get(0) : null); + return writableMediaTypes.stream() + .filter(MediaType::isConcrete) + .findFirst().orElse(null); } } diff --git a/spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTest.java b/spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTest.java new file mode 100644 index 00000000000..c79325313ce --- /dev/null +++ b/spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTest.java @@ -0,0 +1,55 @@ +package org.springframework.http.codec; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Collections; + +import org.junit.Test; +import reactor.core.publisher.Mono; + +import org.springframework.core.ResolvableType; +import org.springframework.core.codec.ByteBufferEncoder; +import org.springframework.http.MediaType; +import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse; +import org.springframework.tests.TestSubscriber; +import org.springframework.util.MimeTypeUtils; + +/** + * Unit tests for {@link EncoderHttpMessageWriter}. + * + * @author Marcin Kamionowski + */ +public class EncoderHttpMessageWriterTest { + + private EncoderHttpMessageWriter writer = new EncoderHttpMessageWriter<>(new ByteBufferEncoder()); + + private MockServerHttpResponse response = new MockServerHttpResponse(); + + @Test + public void writableMediaTypes() throws Exception { + assertThat(writer.getWritableMediaTypes(), containsInAnyOrder(MimeTypeUtils.ALL)); + } + + @Test + public void supportedMediaTypes() throws Exception { + assertTrue(writer.canWrite(ResolvableType.forClass(ByteBuffer.class), + MediaType.ALL)); + assertTrue(writer.canWrite(ResolvableType.forClass(ByteBuffer.class), + MediaType.TEXT_PLAIN)); + } + + @Test + public void encodeByteBuffer(){ + String payload = "Buffer payload"; + Mono source = Mono.just(ByteBuffer.wrap(payload.getBytes(StandardCharsets.UTF_8))); + + writer.write(source, ResolvableType.forClass(ByteBuffer.class), + MediaType.APPLICATION_OCTET_STREAM, response, Collections.emptyMap()); + + assertThat(this.response.getHeaders().getContentType(), is(MediaType.APPLICATION_OCTET_STREAM)); + TestSubscriber.subscribe(response.getBodyAsString()).assertComplete().assertValues(payload); + } +} \ No newline at end of file diff --git a/spring-web/src/test/java/org/springframework/http/codec/ResourceHttpMessageWriterTests.java b/spring-web/src/test/java/org/springframework/http/codec/ResourceHttpMessageWriterTests.java index 4a0cbb6d167..eebb170febe 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/ResourceHttpMessageWriterTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/ResourceHttpMessageWriterTests.java @@ -21,17 +21,11 @@ import java.util.Collections; import org.junit.Before; import org.junit.Test; -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.core.ResolvableType; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.core.io.buffer.DataBufferFactory; -import org.springframework.core.io.buffer.DataBufferUtils; -import org.springframework.core.io.buffer.support.DataBufferTestUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpRange; import org.springframework.http.HttpStatus; @@ -82,7 +76,7 @@ public class ResourceHttpMessageWriterTests { assertThat(this.response.getHeaders().getContentLength(), is(39L)); assertThat(this.response.getHeaders().getFirst(HttpHeaders.ACCEPT_RANGES), is("bytes")); - Mono result = reduceToString(this.response.getBody(), this.response.bufferFactory()); + Mono result = response.getBodyAsString(); TestSubscriber.subscribe(result).assertComplete().assertValues("Spring Framework test resource content."); } @@ -98,7 +92,7 @@ public class ResourceHttpMessageWriterTests { assertThat(this.response.getHeaders().getFirst(HttpHeaders.ACCEPT_RANGES), is("bytes")); assertThat(this.response.getHeaders().getContentLength(), is(6L)); - Mono result = reduceToString(this.response.getBody(), this.response.bufferFactory()); + Mono result = response.getBodyAsString(); TestSubscriber.subscribe(result).assertComplete().assertValues("Spring"); } @@ -113,15 +107,4 @@ public class ResourceHttpMessageWriterTests { assertThat(this.response.getStatusCode(), is(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE)); } - private Mono reduceToString(Publisher buffers, DataBufferFactory bufferFactory) { - - return Flux.from(buffers) - .reduce(bufferFactory.allocateBuffer(), (previous, current) -> { - previous.write(current); - DataBufferUtils.release(current); - return previous; - }) - .map(buffer -> DataBufferTestUtils.dumpString(buffer, StandardCharsets.UTF_8)); - } - } diff --git a/spring-web/src/test/java/org/springframework/http/codec/ResourceRegionHttpMessageWriterTests.java b/spring-web/src/test/java/org/springframework/http/codec/ResourceRegionHttpMessageWriterTests.java index 8fa76056bac..c5b60da7c89 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/ResourceRegionHttpMessageWriterTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/ResourceRegionHttpMessageWriterTests.java @@ -16,8 +16,8 @@ package org.springframework.http.codec; -import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; import java.nio.charset.StandardCharsets; import java.util.Collections; @@ -28,17 +28,12 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.core.ResolvableType; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.core.io.buffer.DataBufferFactory; -import org.springframework.core.io.buffer.DataBufferUtils; -import org.springframework.core.io.buffer.support.DataBufferTestUtils; import org.springframework.core.io.support.ResourceRegion; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -94,7 +89,7 @@ public class ResourceRegionHttpMessageWriterTests { assertThat(this.response.getHeaders().getFirst(HttpHeaders.CONTENT_RANGE), is("bytes 0-5/39")); assertThat(this.response.getHeaders().getContentLength(), is(6L)); - Mono result = reduceToString(this.response.getBody(), this.response.bufferFactory()); + Mono result = response.getBodyAsString(); TestSubscriber.subscribe(result).assertComplete().assertValues("Spring"); } @@ -118,7 +113,7 @@ public class ResourceRegionHttpMessageWriterTests { HttpHeaders headers = this.response.getHeaders(); assertThat(headers.getContentType().toString(), startsWith("multipart/byteranges;boundary=" + boundary)); - Mono result = reduceToString(this.response.getBody(), this.response.bufferFactory()); + Mono result = response.getBodyAsString(); TestSubscriber .subscribe(result).assertNoError() .assertComplete() @@ -149,15 +144,4 @@ public class ResourceRegionHttpMessageWriterTests { }); } - private Mono reduceToString(Publisher buffers, DataBufferFactory bufferFactory) { - - return Flux.from(buffers) - .reduce(bufferFactory.allocateBuffer(), (previous, current) -> { - previous.write(current); - DataBufferUtils.release(current); - return previous; - }) - .map(buffer -> DataBufferTestUtils.dumpString(buffer, StandardCharsets.UTF_8)); - } - } diff --git a/spring-web/src/test/java/org/springframework/mock/http/server/reactive/test/MockServerHttpResponse.java b/spring-web/src/test/java/org/springframework/mock/http/server/reactive/test/MockServerHttpResponse.java index 5e2b9c16ca6..dc5fc3523b6 100644 --- a/spring-web/src/test/java/org/springframework/mock/http/server/reactive/test/MockServerHttpResponse.java +++ b/spring-web/src/test/java/org/springframework/mock/http/server/reactive/test/MockServerHttpResponse.java @@ -16,6 +16,7 @@ package org.springframework.mock.http.server.reactive.test; +import java.nio.charset.StandardCharsets; import java.util.function.Supplier; import org.reactivestreams.Publisher; @@ -24,7 +25,9 @@ import reactor.core.publisher.Mono; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferFactory; +import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.core.io.buffer.DefaultDataBufferFactory; +import org.springframework.core.io.buffer.support.DataBufferTestUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseCookie; @@ -57,6 +60,7 @@ public class MockServerHttpResponse implements ServerHttpResponse { return true; } + @Override public HttpStatus getStatusCode() { return this.status; } @@ -105,4 +109,16 @@ public class MockServerHttpResponse implements ServerHttpResponse { return this.bufferFactory; } + public Mono getBodyAsString() { + + return Flux.from(body) + .reduce(bufferFactory.allocateBuffer(), (previous, current) -> { + previous.write(current); + DataBufferUtils.release(current); + return previous; + }) + .map(buffer -> DataBufferTestUtils.dumpString(buffer, StandardCharsets.UTF_8)); + } + + }