Minor revision of reactive support layout (ahead of 5.0 M1)
DataSourceUtils moved to main core.io.buffer package. Consistently named Jackson2JsonDecoder/Encoder and Jaxb2XmlDecoder/Encoder. Plenty of related polishing.
This commit is contained in:
@@ -28,12 +28,15 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
/**
|
||||
* Abstract base class for Jackson based decoder/encoder implementations.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class AbstractJacksonJsonCodec {
|
||||
public class AbstractJackson2Codec {
|
||||
|
||||
protected static final List<MimeType> JSON_MIME_TYPES = Arrays.asList(
|
||||
new MimeType("application", "json", StandardCharsets.UTF_8),
|
||||
@@ -42,10 +45,17 @@ public class AbstractJacksonJsonCodec {
|
||||
|
||||
protected final ObjectMapper mapper;
|
||||
|
||||
protected AbstractJacksonJsonCodec(ObjectMapper mapper) {
|
||||
|
||||
/**
|
||||
* Create a new Jackson codec for the given mapper.
|
||||
* @param mapper the Jackson ObjectMapper to use
|
||||
*/
|
||||
protected AbstractJackson2Codec(ObjectMapper mapper) {
|
||||
Assert.notNull(mapper, "ObjectMapper must not be null");
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the Jackson {@link JavaType} for the specified type and context class.
|
||||
* <p>The default implementation returns {@code typeFactory.constructType(type, contextClass)},
|
||||
@@ -32,35 +32,35 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.CodecException;
|
||||
import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.support.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
|
||||
/**
|
||||
* Decode a byte stream into JSON and convert to Object's with Jackson.
|
||||
* Decode a byte stream into JSON and convert to Object's with Jackson 2.6+.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
* @see JacksonJsonEncoder
|
||||
* @see Jackson2JsonEncoder
|
||||
*/
|
||||
public class JacksonJsonDecoder extends AbstractJacksonJsonCodec implements Decoder<Object> {
|
||||
public class Jackson2JsonDecoder extends AbstractJackson2Codec implements Decoder<Object> {
|
||||
|
||||
private final JsonObjectDecoder fluxObjectDecoder = new JsonObjectDecoder(true);
|
||||
|
||||
private final JsonObjectDecoder monoObjectDecoder = new JsonObjectDecoder(false);
|
||||
|
||||
|
||||
public JacksonJsonDecoder() {
|
||||
public Jackson2JsonDecoder() {
|
||||
super(Jackson2ObjectMapperBuilder.json().build());
|
||||
}
|
||||
|
||||
public JacksonJsonDecoder(ObjectMapper mapper) {
|
||||
public Jackson2JsonDecoder(ObjectMapper mapper) {
|
||||
super(mapper);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canDecode(ResolvableType elementType, MimeType mimeType, Object... hints) {
|
||||
if (mimeType == null) {
|
||||
@@ -96,23 +96,23 @@ public class JacksonJsonDecoder extends AbstractJacksonJsonCodec implements Deco
|
||||
Assert.notNull(inputStream, "'inputStream' must not be null");
|
||||
Assert.notNull(elementType, "'elementType' must not be null");
|
||||
|
||||
MethodParameter methodParameter = (elementType.getSource() instanceof MethodParameter ?
|
||||
(MethodParameter)elementType.getSource() : null);
|
||||
Class<?> contextClass = (methodParameter != null ? methodParameter.getContainingClass() : null);
|
||||
MethodParameter methodParam = (elementType.getSource() instanceof MethodParameter ?
|
||||
(MethodParameter) elementType.getSource() : null);
|
||||
Class<?> contextClass = (methodParam != null ? methodParam.getContainingClass() : null);
|
||||
JavaType javaType = getJavaType(elementType.getType(), contextClass);
|
||||
ObjectReader reader;
|
||||
|
||||
if (methodParameter != null && methodParameter.getParameter().getAnnotation(JsonView.class) != null) {
|
||||
JsonView annotation = methodParameter.getParameter().getAnnotation(JsonView.class);
|
||||
Class<?>[] classes = annotation.value();
|
||||
ObjectReader reader;
|
||||
JsonView jsonView = (methodParam != null ? methodParam.getParameterAnnotation(JsonView.class) : null);
|
||||
if (jsonView != null) {
|
||||
Class<?>[] classes = jsonView.value();
|
||||
if (classes.length != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"@JsonView only supported for response body advice with exactly 1 class argument: " + methodParameter);
|
||||
throw new IllegalArgumentException("@JsonView only supported for response body advice " +
|
||||
"with exactly 1 class argument: " + methodParam);
|
||||
}
|
||||
reader = mapper.readerWithView(classes[0]).forType(javaType);
|
||||
reader = this.mapper.readerWithView(classes[0]).forType(javaType);
|
||||
}
|
||||
else {
|
||||
reader = mapper.readerFor(javaType);
|
||||
reader = this.mapper.readerFor(javaType);
|
||||
}
|
||||
|
||||
return objectDecoder.decode(inputStream, elementType, mimeType, hints)
|
||||
@@ -122,8 +122,8 @@ public class JacksonJsonDecoder extends AbstractJacksonJsonCodec implements Deco
|
||||
DataBufferUtils.release(dataBuffer);
|
||||
return value;
|
||||
}
|
||||
catch (IOException e) {
|
||||
return Flux.error(new CodecException("Error while reading the data", e));
|
||||
catch (IOException ex) {
|
||||
return Flux.error(new CodecException("Error while reading the data", ex));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -41,14 +41,15 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
/**
|
||||
* Encode from an {@code Object} stream to a byte stream of JSON objects.
|
||||
* Encode from an {@code Object} stream to a byte stream of JSON objects,
|
||||
* using Jackson 2.6+.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Arjen Poutsma
|
||||
* @since 5.0
|
||||
* @see JacksonJsonDecoder
|
||||
* @see Jackson2JsonDecoder
|
||||
*/
|
||||
public class JacksonJsonEncoder extends AbstractJacksonJsonCodec implements Encoder<Object> {
|
||||
public class Jackson2JsonEncoder extends AbstractJackson2Codec implements Encoder<Object> {
|
||||
|
||||
private static final ByteBuffer START_ARRAY_BUFFER = ByteBuffer.wrap(new byte[]{'['});
|
||||
|
||||
@@ -57,14 +58,15 @@ public class JacksonJsonEncoder extends AbstractJacksonJsonCodec implements Enco
|
||||
private static final ByteBuffer END_ARRAY_BUFFER = ByteBuffer.wrap(new byte[]{']'});
|
||||
|
||||
|
||||
public JacksonJsonEncoder() {
|
||||
public Jackson2JsonEncoder() {
|
||||
super(Jackson2ObjectMapperBuilder.json().build());
|
||||
}
|
||||
|
||||
public JacksonJsonEncoder(ObjectMapper mapper) {
|
||||
public Jackson2JsonEncoder(ObjectMapper mapper) {
|
||||
super(mapper);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canEncode(ResolvableType elementType, MimeType mimeType, Object... hints) {
|
||||
if (mimeType == null) {
|
||||
@@ -105,38 +107,38 @@ public class JacksonJsonEncoder extends AbstractJacksonJsonCodec implements Enco
|
||||
private DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory, ResolvableType type) {
|
||||
TypeFactory typeFactory = this.mapper.getTypeFactory();
|
||||
JavaType javaType = typeFactory.constructType(type.getType());
|
||||
MethodParameter returnType = (type.getSource() instanceof MethodParameter ?
|
||||
(MethodParameter)type.getSource() : null);
|
||||
MethodParameter returnType =
|
||||
(type.getSource() instanceof MethodParameter ? (MethodParameter) type.getSource() : null);
|
||||
|
||||
if (type != null && value != null && type.isAssignableFrom(value.getClass())) {
|
||||
if (type.isInstance(value)) {
|
||||
javaType = getJavaType(type.getType(), null);
|
||||
}
|
||||
ObjectWriter writer;
|
||||
|
||||
if (returnType != null && returnType.getMethodAnnotation(JsonView.class) != null) {
|
||||
JsonView annotation = returnType.getMethodAnnotation(JsonView.class);
|
||||
Class<?>[] classes = annotation.value();
|
||||
ObjectWriter writer;
|
||||
JsonView jsonView = (returnType != null ? returnType.getMethodAnnotation(JsonView.class) : null);
|
||||
if (jsonView != null) {
|
||||
Class<?>[] classes = jsonView.value();
|
||||
if (classes.length != 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"@JsonView only supported for response body advice with exactly 1 class argument: " + returnType);
|
||||
throw new IllegalArgumentException("@JsonView only supported for response body advice " +
|
||||
"with exactly 1 class argument: " + returnType);
|
||||
}
|
||||
writer = this.mapper.writerWithView(classes[0]);
|
||||
}
|
||||
else {
|
||||
writer = this.mapper.writer();
|
||||
}
|
||||
|
||||
if (javaType != null && javaType.isContainerType()) {
|
||||
writer = writer.forType(javaType);
|
||||
}
|
||||
|
||||
DataBuffer buffer = bufferFactory.allocateBuffer();
|
||||
OutputStream outputStream = buffer.asOutputStream();
|
||||
|
||||
try {
|
||||
writer.writeValue(outputStream, value);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new CodecException("Error while writing the data", e);
|
||||
catch (IOException ex) {
|
||||
throw new CodecException("Error while writing the data", ex);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
@@ -31,7 +31,7 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.AbstractDecoder;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferFactory;
|
||||
import org.springframework.core.io.buffer.support.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
/**
|
||||
@@ -109,17 +109,17 @@ class JsonObjectDecoder extends AbstractDecoder<DataBuffer> {
|
||||
Integer writerIndex;
|
||||
|
||||
@Override
|
||||
public Publisher<? extends DataBuffer> apply(DataBuffer b) {
|
||||
public Publisher<? extends DataBuffer> apply(DataBuffer buffer) {
|
||||
List<DataBuffer> chunks = new ArrayList<>();
|
||||
if (this.input == null) {
|
||||
this.input = Unpooled.copiedBuffer(b.asByteBuffer());
|
||||
DataBufferUtils.release(b);
|
||||
this.input = Unpooled.copiedBuffer(buffer.asByteBuffer());
|
||||
DataBufferUtils.release(buffer);
|
||||
this.writerIndex = this.input.writerIndex();
|
||||
}
|
||||
else {
|
||||
this.input = Unpooled.copiedBuffer(this.input,
|
||||
Unpooled.copiedBuffer(b.asByteBuffer()));
|
||||
DataBufferUtils.release(b);
|
||||
Unpooled.copiedBuffer(buffer.asByteBuffer()));
|
||||
DataBufferUtils.release(buffer);
|
||||
this.writerIndex = this.input.writerIndex();
|
||||
}
|
||||
if (this.state == ST_CORRUPTED) {
|
||||
@@ -133,7 +133,7 @@ class JsonObjectDecoder extends AbstractDecoder<DataBuffer> {
|
||||
return Flux.error(new IllegalStateException("object length exceeds " +
|
||||
maxObjectLength + ": " + this.writerIndex + " bytes discarded"));
|
||||
}
|
||||
DataBufferFactory dataBufferFactory = b.factory();
|
||||
DataBufferFactory dataBufferFactory = buffer.factory();
|
||||
for (/* use current index */; this.index < this.writerIndex; this.index++) {
|
||||
byte c = this.input.getByte(this.index);
|
||||
if (this.state == ST_DECODING_NORMAL) {
|
||||
|
||||
@@ -50,9 +50,9 @@ import org.springframework.util.xml.StaxUtils;
|
||||
* @author Sebastien Deleuze
|
||||
* @author Arjen Poutsma
|
||||
* @since 5.0
|
||||
* @see Jaxb2Encoder
|
||||
* @see Jaxb2XmlEncoder
|
||||
*/
|
||||
public class Jaxb2Decoder extends AbstractDecoder<Object> {
|
||||
public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
|
||||
|
||||
/**
|
||||
* The default value for JAXB annotations.
|
||||
@@ -61,14 +61,15 @@ public class Jaxb2Decoder extends AbstractDecoder<Object> {
|
||||
* @see XmlType#name()
|
||||
* @see XmlType#namespace()
|
||||
*/
|
||||
private final static String JAXB_DEFAULT_ANNOTATION_VALUE = "##default";
|
||||
private static final String JAXB_DEFAULT_ANNOTATION_VALUE = "##default";
|
||||
|
||||
|
||||
private final XmlEventDecoder xmlEventDecoder = new XmlEventDecoder();
|
||||
|
||||
private final JaxbContextContainer jaxbContexts = new JaxbContextContainer();
|
||||
|
||||
|
||||
public Jaxb2Decoder() {
|
||||
public Jaxb2XmlDecoder() {
|
||||
super(MimeTypeUtils.APPLICATION_XML, MimeTypeUtils.TEXT_XML);
|
||||
}
|
||||
|
||||
@@ -39,22 +39,24 @@ import org.springframework.util.MimeTypeUtils;
|
||||
* @author Sebastien Deleuze
|
||||
* @author Arjen Poutsma
|
||||
* @since 5.0
|
||||
* @see Jaxb2Decoder
|
||||
* @see Jaxb2XmlDecoder
|
||||
*/
|
||||
public class Jaxb2Encoder extends AbstractSingleValueEncoder<Object> {
|
||||
public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> {
|
||||
|
||||
private final JaxbContextContainer jaxbContexts = new JaxbContextContainer();
|
||||
|
||||
public Jaxb2Encoder() {
|
||||
|
||||
public Jaxb2XmlEncoder() {
|
||||
super(MimeTypeUtils.APPLICATION_XML, MimeTypeUtils.TEXT_XML);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canEncode(ResolvableType elementType, MimeType mimeType, Object... hints) {
|
||||
if (super.canEncode(elementType, mimeType, hints)) {
|
||||
Class<?> outputClass = elementType.getRawClass();
|
||||
return outputClass.isAnnotationPresent(XmlRootElement.class) ||
|
||||
outputClass.isAnnotationPresent(XmlType.class);
|
||||
return (outputClass.isAnnotationPresent(XmlRootElement.class) ||
|
||||
outputClass.isAnnotationPresent(XmlType.class));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@@ -80,7 +82,4 @@ public class Jaxb2Encoder extends AbstractSingleValueEncoder<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ import reactor.core.publisher.Mono;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.AbstractDecoder;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.support.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
@@ -65,30 +65,32 @@ import org.springframework.util.MimeTypeUtils;
|
||||
* <li>{@link javax.xml.stream.events.EndElement} {@code root}</li>
|
||||
* </ol>
|
||||
*
|
||||
* Note that this decoder is not registered by default, but used internally by other
|
||||
* decoders who are.
|
||||
* Note that this decoder is not registered by default but used internally
|
||||
* by other decoders who are there by default.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 5.0
|
||||
*/
|
||||
public class XmlEventDecoder extends AbstractDecoder<XMLEvent> {
|
||||
|
||||
private static final boolean aaltoPresent = ClassUtils
|
||||
.isPresent("com.fasterxml.aalto.AsyncXMLStreamReader",
|
||||
XmlEventDecoder.class.getClassLoader());
|
||||
private static final boolean aaltoPresent = ClassUtils.isPresent(
|
||||
"com.fasterxml.aalto.AsyncXMLStreamReader", XmlEventDecoder.class.getClassLoader());
|
||||
|
||||
private static final XMLInputFactory inputFactory = XMLInputFactory.newFactory();
|
||||
|
||||
boolean useAalto = true;
|
||||
|
||||
|
||||
public XmlEventDecoder() {
|
||||
super(MimeTypeUtils.APPLICATION_XML, MimeTypeUtils.TEXT_XML);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Flux<XMLEvent> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType,
|
||||
MimeType mimeType, Object... hints) {
|
||||
|
||||
Flux<DataBuffer> flux = Flux.from(inputStream);
|
||||
if (useAalto && aaltoPresent) {
|
||||
return flux.flatMap(new AaltoDataBufferToXmlEvent());
|
||||
@@ -112,11 +114,11 @@ public class XmlEventDecoder extends AbstractDecoder<XMLEvent> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Separate static class to isolate Aalto dependency.
|
||||
*/
|
||||
private static class AaltoDataBufferToXmlEvent
|
||||
implements Function<DataBuffer, Publisher<? extends XMLEvent>> {
|
||||
private static class AaltoDataBufferToXmlEvent implements Function<DataBuffer, Publisher<? extends XMLEvent>> {
|
||||
|
||||
private static final AsyncXMLInputFactory inputFactory = new InputFactoryImpl();
|
||||
|
||||
@@ -154,4 +156,5 @@ public class XmlEventDecoder extends AbstractDecoder<XMLEvent> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.reactivestreams.Subscriber;
|
||||
import org.reactivestreams.Subscription;
|
||||
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.support.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,15 +38,15 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.reactive.ClientHttpConnector;
|
||||
import org.springframework.http.client.reactive.ClientHttpRequest;
|
||||
import org.springframework.http.client.reactive.ClientHttpResponse;
|
||||
import org.springframework.http.codec.json.JacksonJsonDecoder;
|
||||
import org.springframework.http.codec.json.JacksonJsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2Decoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2Encoder;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlDecoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -106,8 +106,8 @@ public final class WebClient {
|
||||
* <ul>
|
||||
* <li>{@link ByteBufferEncoder} / {@link ByteBufferDecoder}</li>
|
||||
* <li>{@link CharSequenceEncoder} / {@link StringDecoder}</li>
|
||||
* <li>{@link Jaxb2Encoder} / {@link Jaxb2Decoder}</li>
|
||||
* <li>{@link JacksonJsonEncoder} / {@link JacksonJsonDecoder}</li>
|
||||
* <li>{@link Jaxb2XmlEncoder} / {@link Jaxb2XmlDecoder}</li>
|
||||
* <li>{@link Jackson2JsonEncoder} / {@link Jackson2JsonDecoder}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param clientHttpConnector the {@code ClientHttpRequestFactory} to use
|
||||
@@ -126,10 +126,10 @@ public final class WebClient {
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(new StringDecoder(false)));
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(new ResourceDecoder()));
|
||||
if (jaxb2Present) {
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(new Jaxb2Decoder()));
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder()));
|
||||
}
|
||||
if (jackson2Present) {
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(new JacksonJsonDecoder()));
|
||||
messageReaders.add(new DecoderHttpMessageReader<>(new Jackson2JsonDecoder()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,10 +141,10 @@ public final class WebClient {
|
||||
messageWriters.add(new EncoderHttpMessageWriter<>(new CharSequenceEncoder()));
|
||||
messageWriters.add(new ResourceHttpMessageWriter());
|
||||
if (jaxb2Present) {
|
||||
messageWriters.add(new EncoderHttpMessageWriter<>(new Jaxb2Encoder()));
|
||||
messageWriters.add(new EncoderHttpMessageWriter<>(new Jaxb2XmlEncoder()));
|
||||
}
|
||||
if (jackson2Present) {
|
||||
messageWriters.add(new EncoderHttpMessageWriter<>(new JacksonJsonEncoder()));
|
||||
messageWriters.add(new EncoderHttpMessageWriter<>(new Jackson2JsonEncoder()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,7 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
import org.springframework.http.codec.SseEvent;
|
||||
import org.springframework.http.codec.SseEventHttpMessageWriter;
|
||||
import org.springframework.http.codec.json.JacksonJsonEncoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@@ -39,11 +36,11 @@ import static org.junit.Assert.*;
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class SseEventHttpMessageWriterTests
|
||||
extends AbstractDataBufferAllocatingTestCase {
|
||||
public class SseEventHttpMessageWriterTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
private SseEventHttpMessageWriter converter = new SseEventHttpMessageWriter(
|
||||
Collections.singletonList(new JacksonJsonEncoder()));
|
||||
Collections.singletonList(new Jackson2JsonEncoder()));
|
||||
|
||||
|
||||
@Test
|
||||
public void nullMimeType() {
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -33,19 +32,19 @@ import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link JacksonJsonDecoder}.
|
||||
* Unit tests for {@link Jackson2JsonDecoder}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class JacksonJsonDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
@Test
|
||||
public void canDecode() {
|
||||
JacksonJsonDecoder decoder = new JacksonJsonDecoder();
|
||||
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder();
|
||||
|
||||
assertTrue(decoder.canDecode(null, MediaType.APPLICATION_JSON));
|
||||
assertFalse(decoder.canDecode(null, MediaType.APPLICATION_XML));
|
||||
@@ -55,7 +54,7 @@ public class JacksonJsonDecoderTests extends AbstractDataBufferAllocatingTestCas
|
||||
public void decodePojo() {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foo\": \"foofoo\", \"bar\": \"barbar\"}"));
|
||||
ResolvableType elementType = ResolvableType.forClass(Pojo.class);
|
||||
Flux<Object> flux = new JacksonJsonDecoder().decode(source, elementType, null);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null);
|
||||
|
||||
TestSubscriber.subscribe(flux).assertNoError().assertComplete().
|
||||
assertValues(new Pojo("foofoo", "barbar"));
|
||||
@@ -68,7 +67,7 @@ public class JacksonJsonDecoderTests extends AbstractDataBufferAllocatingTestCas
|
||||
|
||||
Method method = getClass().getDeclaredMethod("handle", List.class);
|
||||
ResolvableType elementType = ResolvableType.forMethodParameter(method, 0);
|
||||
Mono<Object> mono = new JacksonJsonDecoder().decodeToMono(source, elementType, null);
|
||||
Mono<Object> mono = new Jackson2JsonDecoder().decodeToMono(source, elementType, null);
|
||||
|
||||
TestSubscriber.subscribe(mono).assertNoError().assertComplete().
|
||||
assertValues(Arrays.asList(new Pojo("f1", "b1"), new Pojo("f2", "b2")));
|
||||
@@ -80,7 +79,7 @@ public class JacksonJsonDecoderTests extends AbstractDataBufferAllocatingTestCas
|
||||
"[{\"bar\":\"b1\",\"foo\":\"f1\"},{\"bar\":\"b2\",\"foo\":\"f2\"}]"));
|
||||
|
||||
ResolvableType elementType = ResolvableType.forClass(Pojo.class);
|
||||
Flux<Object> flux = new JacksonJsonDecoder().decode(source, elementType, null);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null);
|
||||
|
||||
TestSubscriber.subscribe(flux).assertNoError().assertComplete().
|
||||
assertValues(new Pojo("f1", "b1"), new Pojo("f2", "b2"));
|
||||
@@ -92,7 +91,7 @@ public class JacksonJsonDecoderTests extends AbstractDataBufferAllocatingTestCas
|
||||
stringBuffer("{\"withView1\" : \"with\", \"withView2\" : \"with\", \"withoutView\" : \"without\"}"));
|
||||
ResolvableType elementType = ResolvableType
|
||||
.forMethodParameter(JacksonController.class.getMethod("foo", JacksonViewBean.class), 0);
|
||||
Flux<JacksonViewBean> flux = new JacksonJsonDecoder()
|
||||
Flux<JacksonViewBean> flux = new Jackson2JsonDecoder()
|
||||
.decode(source, elementType, null).cast(JacksonViewBean.class);
|
||||
|
||||
TestSubscriber
|
||||
@@ -106,13 +105,16 @@ public class JacksonJsonDecoderTests extends AbstractDataBufferAllocatingTestCas
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void handle(List<Pojo> list) {
|
||||
}
|
||||
|
||||
|
||||
private interface MyJacksonView1 {}
|
||||
|
||||
private interface MyJacksonView2 {}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class JacksonViewBean {
|
||||
|
||||
@@ -149,6 +151,7 @@ public class JacksonJsonDecoderTests extends AbstractDataBufferAllocatingTestCas
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class JacksonController {
|
||||
|
||||
public JacksonViewBean foo(@JsonView(MyJacksonView1.class) JacksonViewBean bean) {
|
||||
@@ -19,7 +19,6 @@ package org.springframework.http.codec.json;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -31,21 +30,14 @@ import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class JacksonJsonEncoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class Jackson2JsonEncoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
private JacksonJsonEncoder encoder;
|
||||
|
||||
|
||||
@Before
|
||||
public void createEncoder() {
|
||||
this.encoder = new JacksonJsonEncoder();
|
||||
}
|
||||
private final Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
|
||||
|
||||
|
||||
@Test
|
||||
@@ -123,10 +115,12 @@ public class JacksonJsonEncoderTests extends AbstractDataBufferAllocatingTestCas
|
||||
private static class Bar extends ParentClass {
|
||||
}
|
||||
|
||||
|
||||
private interface MyJacksonView1 {}
|
||||
|
||||
private interface MyJacksonView2 {}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class JacksonViewBean {
|
||||
|
||||
@@ -163,6 +157,7 @@ public class JacksonJsonEncoderTests extends AbstractDataBufferAllocatingTestCas
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class JacksonController {
|
||||
|
||||
@JsonView(MyJacksonView1.class)
|
||||
@@ -30,7 +30,6 @@ import org.springframework.core.io.buffer.DataBuffer;
|
||||
*/
|
||||
public class JsonObjectDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
|
||||
@Test
|
||||
public void decodeSingleChunkToJsonObject() {
|
||||
JsonObjectDecoder decoder = new JsonObjectDecoder();
|
||||
@@ -82,6 +81,7 @@ public class JsonObjectDecoderTests extends AbstractDataBufferAllocatingTestCase
|
||||
"{\"foo\": \"foofoofoo\", \"bar\": \"barbarbar\"}");
|
||||
}
|
||||
|
||||
|
||||
private static String toString(DataBuffer buffer) {
|
||||
byte[] b = new byte[buffer.readableByteCount()];
|
||||
buffer.read(b);
|
||||
|
||||
@@ -36,14 +36,12 @@ import org.springframework.http.codec.xml.jaxb.XmlType;
|
||||
import org.springframework.http.codec.xml.jaxb.XmlTypeWithName;
|
||||
import org.springframework.http.codec.xml.jaxb.XmlTypeWithNameAndNamespace;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class Jaxb2DecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
private static final String POJO_ROOT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<pojo>" +
|
||||
@@ -64,7 +62,8 @@ public class Jaxb2DecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
"</pojo>" +
|
||||
"<root/>";
|
||||
|
||||
private final Jaxb2Decoder decoder = new Jaxb2Decoder();
|
||||
|
||||
private final Jaxb2XmlDecoder decoder = new Jaxb2XmlDecoder();
|
||||
|
||||
private final XmlEventDecoder xmlEventDecoder = new XmlEventDecoder();
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.http.codec.xml;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.TestSubscriber;
|
||||
@@ -26,28 +25,22 @@ import reactor.test.TestSubscriber;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.support.DataBufferTestUtils;
|
||||
import org.springframework.core.io.buffer.support.DataBufferUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.xmlunit.matchers.CompareMatcher.isSimilarTo;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.xmlunit.matchers.CompareMatcher.*;
|
||||
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class Jaxb2EncoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class Jaxb2XmlEncoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
private Jaxb2Encoder encoder;
|
||||
private final Jaxb2XmlEncoder encoder = new Jaxb2XmlEncoder();
|
||||
|
||||
@Before
|
||||
public void createEncoder() {
|
||||
this.encoder = new Jaxb2Encoder();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canEncode() {
|
||||
@@ -59,7 +52,7 @@ public class Jaxb2EncoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
MediaType.APPLICATION_JSON));
|
||||
|
||||
assertTrue(this.encoder.canEncode(
|
||||
ResolvableType.forClass(Jaxb2DecoderTests.TypePojo.class),
|
||||
ResolvableType.forClass(Jaxb2XmlDecoderTests.TypePojo.class),
|
||||
MediaType.APPLICATION_XML));
|
||||
|
||||
assertFalse(this.encoder.canEncode(ResolvableType.forClass(getClass()),
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* 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.web.client.reactive;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@@ -19,18 +35,14 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.reactive.ClientHttpResponse;
|
||||
import org.springframework.http.codec.json.JacksonJsonDecoder;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.BDDMockito.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.BDDMockito.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
@@ -40,7 +52,7 @@ import static org.mockito.Mockito.mock;
|
||||
*/
|
||||
public class ResponseExtractorsTests {
|
||||
|
||||
private HttpHeaders headers = new HttpHeaders();
|
||||
private HttpHeaders headers;
|
||||
|
||||
private ClientHttpResponse response;
|
||||
|
||||
@@ -50,6 +62,7 @@ public class ResponseExtractorsTests {
|
||||
|
||||
private ResponseErrorHandler errorHandler;
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
this.headers = new HttpHeaders();
|
||||
@@ -57,13 +70,14 @@ public class ResponseExtractorsTests {
|
||||
given(this.response.getHeaders()).willReturn(headers);
|
||||
this.messageReaders = Arrays.asList(
|
||||
new DecoderHttpMessageReader<>(new StringDecoder()),
|
||||
new DecoderHttpMessageReader<>(new JacksonJsonDecoder()));
|
||||
new DecoderHttpMessageReader<>(new Jackson2JsonDecoder()));
|
||||
this.webClientConfig = mock(WebClientConfig.class);
|
||||
this.errorHandler = mock(ResponseErrorHandler.class);
|
||||
given(this.webClientConfig.getMessageReaders()).willReturn(this.messageReaders);
|
||||
given(this.webClientConfig.getResponseErrorHandler()).willReturn(this.errorHandler);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void shouldExtractResponseEntityMono() throws Exception {
|
||||
this.headers.setContentType(MediaType.TEXT_PLAIN);
|
||||
@@ -189,7 +203,6 @@ public class ResponseExtractorsTests {
|
||||
|
||||
|
||||
private Flux<DataBuffer> createFluxBody(String... items) throws Exception {
|
||||
|
||||
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
|
||||
return Flux.just(items)
|
||||
.map(item -> {
|
||||
@@ -204,7 +217,9 @@ public class ResponseExtractorsTests {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
protected class SomePojo {
|
||||
|
||||
public String foo;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user