Polish + minor refactoring of SSE reader and writer
Instead of accepting List<Encoder|Decoder> and then look for the first to support JSON, always expect a single JSON [Encoder|Decoder] and use that unconditionally. When writing use the nested ResolvableType instead of the Class of the actual value which should better support generics. Remove the SSE hint and pass "text/event-stream" as the media type instead to serve as a hint. We are expecting a JSON encoder and using it unconditionally in any case so this should be good enough.
This commit is contained in:
@@ -21,7 +21,6 @@ import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
@@ -39,8 +38,8 @@ import static org.junit.Assert.assertTrue;
|
||||
*/
|
||||
public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
private ServerSentEventHttpMessageReader messageReader = new ServerSentEventHttpMessageReader(
|
||||
Collections.singletonList(new Jackson2JsonDecoder()));
|
||||
private ServerSentEventHttpMessageReader messageReader =
|
||||
new ServerSentEventHttpMessageReader(new Jackson2JsonDecoder());
|
||||
|
||||
@Test
|
||||
public void cantRead() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -18,14 +18,15 @@ package org.springframework.http.codec;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
@@ -34,49 +35,45 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.core.ResolvableType.forClass;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ServerSentEventHttpMessageWriter}.
|
||||
* @author Sebastien Deleuze
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
private ServerSentEventHttpMessageWriter messageWriter = new ServerSentEventHttpMessageWriter(
|
||||
Collections.singletonList(new Jackson2JsonEncoder()));
|
||||
public static final Map<String, Object> HINTS = Collections.emptyMap();
|
||||
|
||||
private ServerSentEventHttpMessageWriter messageWriter =
|
||||
new ServerSentEventHttpMessageWriter(new Jackson2JsonEncoder());
|
||||
|
||||
|
||||
@Test
|
||||
public void cantRead() {
|
||||
assertFalse(messageWriter.canWrite(ResolvableType.forClass(Object.class),
|
||||
new MediaType("foo", "bar")));
|
||||
public void canWrite() {
|
||||
assertTrue(this.messageWriter.canWrite(forClass(Object.class), null));
|
||||
assertTrue(this.messageWriter.canWrite(null, MediaType.TEXT_EVENT_STREAM));
|
||||
assertTrue(this.messageWriter.canWrite(forClass(ServerSentEvent.class), new MediaType("foo", "bar")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canRead() {
|
||||
assertTrue(messageWriter.canWrite(ResolvableType.forClass(Object.class), null));
|
||||
assertTrue(messageWriter.canWrite(ResolvableType.forClass(Object.class),
|
||||
new MediaType("text", "event-stream")));
|
||||
assertTrue(messageWriter.canWrite(ResolvableType.forClass(ServerSentEvent.class),
|
||||
new MediaType("bar", "bar")));
|
||||
public void canNotWrite() {
|
||||
assertFalse(this.messageWriter.canWrite(forClass(Object.class), new MediaType("foo", "bar")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeServerSentEvent() {
|
||||
ServerSentEvent<String> event = ServerSentEvent.<String>builder().
|
||||
data("bar").id("c42").event("foo").comment("bla\nbla bla\nbla bla bla")
|
||||
.retry(Duration.ofMillis(123L)).build();
|
||||
|
||||
Mono<ServerSentEvent<String>> source = Mono.just(event);
|
||||
ServerSentEvent<?> event = ServerSentEvent.builder().data("bar").id("c42").event("foo")
|
||||
.comment("bla\nbla bla\nbla bla bla").retry(Duration.ofMillis(123L)).build();
|
||||
|
||||
Mono<ServerSentEvent> source = Mono.just(event);
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse();
|
||||
messageWriter.write(source, ResolvableType.forClass(ServerSentEvent.class),
|
||||
new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap()).block(Duration.ofMillis(5000));
|
||||
testWrite(source, outputMessage, ServerSentEvent.class);
|
||||
|
||||
StepVerifier.create(outputMessage.getBodyAsString())
|
||||
.expectNext("id:c42\n" +
|
||||
"event:foo\n" +
|
||||
"retry:123\n" +
|
||||
":bla\n" +
|
||||
":bla bla\n" +
|
||||
":bla bla bla\n" +
|
||||
"data:bar\n\n")
|
||||
.expectNext("id:c42\nevent:foo\nretry:123\n:bla\n:bla bla\n:bla bla bla\ndata:bar\n\n")
|
||||
.expectComplete()
|
||||
.verify();
|
||||
}
|
||||
@@ -85,8 +82,7 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll
|
||||
public void writeString() {
|
||||
Flux<String> source = Flux.just("foo", "bar");
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse();
|
||||
messageWriter.write(source, ResolvableType.forClass(String.class),
|
||||
new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap()).block(Duration.ofMillis(5000));
|
||||
testWrite(source, outputMessage, String.class);
|
||||
|
||||
StepVerifier.create(outputMessage.getBodyAsString())
|
||||
.expectNext("data:foo\n\ndata:bar\n\n")
|
||||
@@ -98,25 +94,19 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll
|
||||
public void writeMultiLineString() {
|
||||
Flux<String> source = Flux.just("foo\nbar", "foo\nbaz");
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse();
|
||||
messageWriter.write(source, ResolvableType.forClass(String.class),
|
||||
new MediaType("text", "event-stream"), outputMessage, Collections.emptyMap()).block(Duration.ofMillis(5000));
|
||||
testWrite(source, outputMessage, String.class);
|
||||
|
||||
StepVerifier.create(outputMessage.getBodyAsString())
|
||||
.expectNext("data:foo\n" +
|
||||
"data:bar\n\n" +
|
||||
"data:foo\n" +
|
||||
"data:baz\n\n")
|
||||
.expectNext("data:foo\ndata:bar\n\ndata:foo\ndata:baz\n\n")
|
||||
.expectComplete()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writePojo() {
|
||||
Flux<Pojo> source = Flux.just(new Pojo("foofoo", "barbar"),
|
||||
new Pojo("foofoofoo", "barbarbar"));
|
||||
Flux<Pojo> source = Flux.just(new Pojo("foofoo", "barbar"), new Pojo("foofoofoo", "barbarbar"));
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse();
|
||||
messageWriter.write(source, ResolvableType.forClass(Pojo.class),
|
||||
MediaType.TEXT_EVENT_STREAM, outputMessage, Collections.emptyMap()).block(Duration.ofMillis(5000));
|
||||
testWrite(source, outputMessage, Pojo.class);
|
||||
|
||||
StepVerifier.create(outputMessage.getBodyAsString())
|
||||
.expectNext("data:{\"foo\":\"foofoo\",\"bar\":\"barbar\"}\n\n" +
|
||||
@@ -127,15 +117,13 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll
|
||||
|
||||
@Test // SPR-14899
|
||||
public void writePojoWithPrettyPrint() {
|
||||
ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().indentOutput(true).build();
|
||||
this.messageWriter = new ServerSentEventHttpMessageWriter(
|
||||
Collections.singletonList(new Jackson2JsonEncoder(mapper)));
|
||||
|
||||
Flux<Pojo> source = Flux.just(new Pojo("foofoo", "barbar"),
|
||||
new Pojo("foofoofoo", "barbarbar"));
|
||||
ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().indentOutput(true).build();
|
||||
this.messageWriter = new ServerSentEventHttpMessageWriter(new Jackson2JsonEncoder(mapper));
|
||||
|
||||
Flux<Pojo> source = Flux.just(new Pojo("foofoo", "barbar"), new Pojo("foofoofoo", "barbarbar"));
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse();
|
||||
messageWriter.write(source, ResolvableType.forClass(Pojo.class),
|
||||
MediaType.TEXT_EVENT_STREAM, outputMessage, Collections.emptyMap()).block(Duration.ofMillis(5000));
|
||||
testWrite(source, outputMessage, Pojo.class);
|
||||
|
||||
StepVerifier.create(outputMessage.getBodyAsString())
|
||||
.expectNext("data:{\n" +
|
||||
@@ -148,4 +136,9 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll
|
||||
.verify();
|
||||
}
|
||||
|
||||
private <T> void testWrite(Publisher<T> source, MockServerHttpResponse outputMessage, Class<T> clazz) {
|
||||
this.messageWriter.write(source, forClass(clazz),
|
||||
MediaType.TEXT_EVENT_STREAM, outputMessage, HINTS).block(Duration.ofMillis(5000));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user