Update Codec API to use Map<String, Object> for hints
Issue: SPR-14557
This commit is contained in:
@@ -38,6 +38,8 @@ import org.springframework.util.MimeType;
|
||||
*/
|
||||
public class AbstractJackson2Codec {
|
||||
|
||||
public static final String JSON_VIEW_HINT = AbstractJackson2Codec.class.getName() + ".jsonView";
|
||||
|
||||
protected static final List<MimeType> JSON_MIME_TYPES = Arrays.asList(
|
||||
new MimeType("application", "json", StandardCharsets.UTF_8),
|
||||
new MimeType("application", "*+json", StandardCharsets.UTF_8));
|
||||
|
||||
@@ -18,8 +18,8 @@ package org.springframework.http.codec.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
@@ -62,7 +62,7 @@ public class Jackson2JsonDecoder extends AbstractJackson2Codec implements Decode
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canDecode(ResolvableType elementType, MimeType mimeType, Object... hints) {
|
||||
public boolean canDecode(ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
|
||||
if (mimeType == null) {
|
||||
return true;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class Jackson2JsonDecoder extends AbstractJackson2Codec implements Decode
|
||||
|
||||
@Override
|
||||
public Flux<Object> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType,
|
||||
MimeType mimeType, Object... hints) {
|
||||
MimeType mimeType, Map<String, Object> hints) {
|
||||
|
||||
JsonObjectDecoder objectDecoder = this.fluxObjectDecoder;
|
||||
return decodeInternal(objectDecoder, inputStream, elementType, mimeType, hints);
|
||||
@@ -84,14 +84,14 @@ public class Jackson2JsonDecoder extends AbstractJackson2Codec implements Decode
|
||||
|
||||
@Override
|
||||
public Mono<Object> decodeToMono(Publisher<DataBuffer> inputStream, ResolvableType elementType,
|
||||
MimeType mimeType, Object... hints) {
|
||||
MimeType mimeType, Map<String, Object> hints) {
|
||||
|
||||
JsonObjectDecoder objectDecoder = this.monoObjectDecoder;
|
||||
return decodeInternal(objectDecoder, inputStream, elementType, mimeType, hints).singleOrEmpty();
|
||||
}
|
||||
|
||||
private Flux<Object> decodeInternal(JsonObjectDecoder objectDecoder, Publisher<DataBuffer> inputStream,
|
||||
ResolvableType elementType, MimeType mimeType, Object[] hints) {
|
||||
ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
|
||||
|
||||
Assert.notNull(inputStream, "'inputStream' must not be null");
|
||||
Assert.notNull(elementType, "'elementType' must not be null");
|
||||
@@ -102,14 +102,10 @@ public class Jackson2JsonDecoder extends AbstractJackson2Codec implements Decode
|
||||
JavaType javaType = getJavaType(elementType.getType(), contextClass);
|
||||
|
||||
ObjectReader reader;
|
||||
JsonView jsonView = (methodParam != null ? methodParam.getParameterAnnotation(JsonView.class) : null);
|
||||
Class<?> jsonView = (Class<?>)hints.get(AbstractJackson2Codec.JSON_VIEW_HINT);
|
||||
|
||||
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: " + methodParam);
|
||||
}
|
||||
reader = this.mapper.readerWithView(classes[0]).forType(javaType);
|
||||
reader = this.mapper.readerWithView(jsonView).forType(javaType);
|
||||
}
|
||||
else {
|
||||
reader = this.mapper.readerFor(javaType);
|
||||
|
||||
@@ -20,8 +20,8 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
@@ -30,7 +30,6 @@ import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.CodecException;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
@@ -68,7 +67,7 @@ public class Jackson2JsonEncoder extends AbstractJackson2Codec implements Encode
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canEncode(ResolvableType elementType, MimeType mimeType, Object... hints) {
|
||||
public boolean canEncode(ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
|
||||
if (mimeType == null) {
|
||||
return true;
|
||||
}
|
||||
@@ -82,14 +81,14 @@ public class Jackson2JsonEncoder extends AbstractJackson2Codec implements Encode
|
||||
|
||||
@Override
|
||||
public Flux<DataBuffer> encode(Publisher<?> inputStream, DataBufferFactory bufferFactory,
|
||||
ResolvableType elementType, MimeType mimeType, Object... hints) {
|
||||
ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
|
||||
|
||||
Assert.notNull(inputStream, "'inputStream' must not be null");
|
||||
Assert.notNull(bufferFactory, "'bufferFactory' must not be null");
|
||||
Assert.notNull(elementType, "'elementType' must not be null");
|
||||
|
||||
if (inputStream instanceof Mono) {
|
||||
return Flux.from(inputStream).map(value -> encodeValue(value, bufferFactory, elementType));
|
||||
return Flux.from(inputStream).map(value -> encodeValue(value, bufferFactory, elementType, hints));
|
||||
}
|
||||
|
||||
Mono<DataBuffer> startArray = Mono.just(bufferFactory.wrap(START_ARRAY_BUFFER));
|
||||
@@ -98,31 +97,25 @@ public class Jackson2JsonEncoder extends AbstractJackson2Codec implements Encode
|
||||
Flux<DataBuffer> array = Flux.from(inputStream)
|
||||
.concatMap(value -> {
|
||||
DataBuffer arraySeparator = bufferFactory.wrap(SEPARATOR_BUFFER);
|
||||
return Flux.just(encodeValue(value, bufferFactory, elementType), arraySeparator);
|
||||
return Flux.just(encodeValue(value, bufferFactory, elementType, hints), arraySeparator);
|
||||
});
|
||||
|
||||
return Flux.concat(startArray, array.skipLast(1), endArray);
|
||||
}
|
||||
|
||||
private DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory, ResolvableType type) {
|
||||
private DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory,
|
||||
ResolvableType type, Map<String, Object> hints) {
|
||||
|
||||
TypeFactory typeFactory = this.mapper.getTypeFactory();
|
||||
JavaType javaType = typeFactory.constructType(type.getType());
|
||||
MethodParameter returnType =
|
||||
(type.getSource() instanceof MethodParameter ? (MethodParameter) type.getSource() : null);
|
||||
|
||||
if (type.isInstance(value)) {
|
||||
javaType = getJavaType(type.getType(), null);
|
||||
}
|
||||
|
||||
ObjectWriter writer;
|
||||
JsonView jsonView = (returnType != null ? returnType.getMethodAnnotation(JsonView.class) : null);
|
||||
Class<?> jsonView = (Class<?>)hints.get(AbstractJackson2Codec.JSON_VIEW_HINT);
|
||||
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);
|
||||
}
|
||||
writer = this.mapper.writerWithView(classes[0]);
|
||||
writer = this.mapper.writerWithView(jsonView);
|
||||
}
|
||||
else {
|
||||
writer = this.mapper.writer();
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.http.codec.json;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -96,7 +97,7 @@ class JsonObjectDecoder extends AbstractDecoder<DataBuffer> {
|
||||
|
||||
@Override
|
||||
public Flux<DataBuffer> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType,
|
||||
MimeType mimeType, Object... hints) {
|
||||
MimeType mimeType, Map<String, Object> hints) {
|
||||
|
||||
return Flux.from(inputStream)
|
||||
.flatMap(new Function<DataBuffer, Publisher<? extends DataBuffer>>() {
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.http.codec.xml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
@@ -75,7 +76,7 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canDecode(ResolvableType elementType, MimeType mimeType, Object... hints) {
|
||||
public boolean canDecode(ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
|
||||
if (super.canDecode(elementType, mimeType, hints)) {
|
||||
Class<?> outputClass = elementType.getRawClass();
|
||||
return outputClass.isAnnotationPresent(XmlRootElement.class) ||
|
||||
@@ -88,11 +89,11 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
|
||||
|
||||
@Override
|
||||
public Flux<Object> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType,
|
||||
MimeType mimeType, Object... hints) {
|
||||
MimeType mimeType, Map<String, Object> hints) {
|
||||
|
||||
Class<?> outputClass = elementType.getRawClass();
|
||||
Flux<XMLEvent> xmlEventFlux =
|
||||
this.xmlEventDecoder.decode(inputStream, null, mimeType);
|
||||
this.xmlEventDecoder.decode(inputStream, null, mimeType, hints);
|
||||
|
||||
QName typeName = toQName(outputClass);
|
||||
Flux<List<XMLEvent>> splitEvents = split(xmlEventFlux, typeName);
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.http.codec.xml;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
@@ -52,7 +53,7 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canEncode(ResolvableType elementType, MimeType mimeType, Object... hints) {
|
||||
public boolean canEncode(ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
|
||||
if (super.canEncode(elementType, mimeType, hints)) {
|
||||
Class<?> outputClass = elementType.getRawClass();
|
||||
return (outputClass.isAnnotationPresent(XmlRootElement.class) ||
|
||||
@@ -66,7 +67,7 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> {
|
||||
|
||||
@Override
|
||||
protected Flux<DataBuffer> encode(Object value, DataBufferFactory dataBufferFactory,
|
||||
ResolvableType type, MimeType mimeType, Object... hints) {
|
||||
ResolvableType type, MimeType mimeType, Map<String, Object> hints) {
|
||||
try {
|
||||
DataBuffer buffer = dataBufferFactory.allocateBuffer(1024);
|
||||
OutputStream outputStream = buffer.asOutputStream();
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.http.codec.xml;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
@@ -89,7 +90,7 @@ public class XmlEventDecoder extends AbstractDecoder<XMLEvent> {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Flux<XMLEvent> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType,
|
||||
MimeType mimeType, Object... hints) {
|
||||
MimeType mimeType, Map<String, Object> hints) {
|
||||
|
||||
Flux<DataBuffer> flux = Flux.from(inputStream);
|
||||
if (useAalto && aaltoPresent) {
|
||||
|
||||
Reference in New Issue
Block a user