This commit is contained in:
Rossen Stoyanchev 2016-10-14 17:16:23 -04:00
parent e5158d47e0
commit 6cb7d51ee5
4 changed files with 98 additions and 15 deletions

View File

@ -16,6 +16,8 @@
package org.springframework.mock.http.server.reactive;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.function.Supplier;
import org.reactivestreams.Publisher;
@ -24,11 +26,14 @@ 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.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseCookie;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@ -106,4 +111,42 @@ public class MockServerHttpResponse implements ServerHttpResponse {
return this.bufferFactory;
}
/**
* Return the body of the response aggregated and converted to a String
* using the charset of the Content-Type response or otherwise defaulting
* to "UTF-8".
*/
public Mono<String> getBodyAsString() {
Charset charset = getCharset();
Charset charsetToUse = (charset != null ? charset : StandardCharsets.UTF_8);
return Flux.from(this.body)
.reduce(this.bufferFactory.allocateBuffer(), (previous, current) -> {
previous.write(current);
DataBufferUtils.release(current);
return previous;
})
.map(buffer -> dumpString(buffer, charsetToUse));
}
private static String dumpString(DataBuffer buffer, Charset charset) {
Assert.notNull(charset, "'charset' must not be null");
byte[] bytes = dumpBytes(buffer);
return new String(bytes, charset);
}
private static byte[] dumpBytes(DataBuffer buffer) {
Assert.notNull(buffer, "'buffer' must not be null");
byte[] bytes = new byte[buffer.readableByteCount()];
buffer.read(bytes);
return bytes;
}
private Charset getCharset() {
MediaType contentType = getHeaders().getContentType();
if (contentType != null) {
return contentType.getCharset();
}
return null;
}
}

View File

@ -1,5 +1,21 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http.codec;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
@ -7,11 +23,13 @@ import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import reactor.core.publisher.Mono;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.ByteBufferEncoder;
import org.springframework.core.codec.Encoder;
import org.springframework.http.MediaType;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.tests.TestSubscriber;
@ -21,35 +39,42 @@ import org.springframework.util.MimeTypeUtils;
* Unit tests for {@link EncoderHttpMessageWriter}.
*
* @author Marcin Kamionowski
* @author Rossen Stoyanchev
*/
public class EncoderHttpMessageWriterTest {
private EncoderHttpMessageWriter<ByteBuffer> writer = new EncoderHttpMessageWriter<>(new ByteBufferEncoder());
private MockServerHttpResponse response = new MockServerHttpResponse();
@Test
public void writableMediaTypes() throws Exception {
EncoderHttpMessageWriter<ByteBuffer> writer = createWriter(new ByteBufferEncoder());
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));
EncoderHttpMessageWriter<ByteBuffer> writer = createWriter(new ByteBufferEncoder());
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<ByteBuffer> source = Mono.just(ByteBuffer.wrap(payload.getBytes(StandardCharsets.UTF_8)));
Mono<ByteBuffer> source = Mono.just(ByteBuffer.wrap(payload.getBytes(UTF_8)));
EncoderHttpMessageWriter<ByteBuffer> writer = createWriter(new ByteBufferEncoder());
writer.write(source, ResolvableType.forClass(ByteBuffer.class),
MediaType.APPLICATION_OCTET_STREAM, response, Collections.emptyMap());
MediaType.APPLICATION_OCTET_STREAM, this.response, Collections.emptyMap());
assertThat(this.response.getHeaders().getContentType(), is(MediaType.APPLICATION_OCTET_STREAM));
TestSubscriber.subscribe(response.getBodyAsString()).assertComplete().assertValues(payload);
TestSubscriber.subscribe(this.response.getBodyAsString()).assertComplete().assertValues(payload);
}
@NotNull
private <T> EncoderHttpMessageWriter<T> createWriter(Encoder<T> encoder) {
return new EncoderHttpMessageWriter<>(encoder);
}
}

View File

@ -76,7 +76,7 @@ public class ResourceHttpMessageWriterTests {
assertThat(this.response.getHeaders().getContentLength(), is(39L));
assertThat(this.response.getHeaders().getFirst(HttpHeaders.ACCEPT_RANGES), is("bytes"));
Mono<String> result = response.getBodyAsString();
Mono<String> result = this.response.getBodyAsString();
TestSubscriber.subscribe(result).assertComplete().assertValues("Spring Framework test resource content.");
}
@ -92,7 +92,7 @@ public class ResourceHttpMessageWriterTests {
assertThat(this.response.getHeaders().getFirst(HttpHeaders.ACCEPT_RANGES), is("bytes"));
assertThat(this.response.getHeaders().getContentLength(), is(6L));
Mono<String> result = response.getBodyAsString();
Mono<String> result = this.response.getBodyAsString();
TestSubscriber.subscribe(result).assertComplete().assertValues("Spring");
}

View File

@ -16,6 +16,7 @@
package org.springframework.mock.http.server.reactive.test;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.function.Supplier;
@ -30,6 +31,7 @@ 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.MediaType;
import org.springframework.http.ResponseCookie;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.LinkedMultiValueMap;
@ -109,16 +111,29 @@ public class MockServerHttpResponse implements ServerHttpResponse {
return this.bufferFactory;
}
/**
* Return the body of the response aggregated and converted to a String
* using the charset of the Content-Type response or otherwise defaulting
* to "UTF-8".
*/
public Mono<String> getBodyAsString() {
return Flux.from(body)
.reduce(bufferFactory.allocateBuffer(), (previous, current) -> {
Charset charset = getCharset();
Charset charsetToUse = (charset != null ? charset : StandardCharsets.UTF_8);
return Flux.from(this.body)
.reduce(this.bufferFactory.allocateBuffer(), (previous, current) -> {
previous.write(current);
DataBufferUtils.release(current);
return previous;
})
.map(buffer -> DataBufferTestUtils.dumpString(buffer, StandardCharsets.UTF_8));
.map(buffer -> DataBufferTestUtils.dumpString(buffer, charsetToUse));
}
private Charset getCharset() {
MediaType contentType = getHeaders().getContentType();
if (contentType != null) {
return contentType.getCharset();
}
return null;
}
}