Add option to encode with an Object value

See gh-22782
This commit is contained in:
Rossen Stoyanchev
2019-04-11 13:50:56 -04:00
parent f89d2ac148
commit 181482fa15
9 changed files with 181 additions and 106 deletions

View File

@@ -119,7 +119,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
if (inputStream instanceof Mono) {
return Mono.from(inputStream).map(value ->
encodeValue(value, mimeType, bufferFactory, elementType, hints, encoding)).flux();
encodeValue(value, bufferFactory, elementType, mimeType, hints, encoding)).flux();
}
else {
return this.streamingMediaTypes.stream()
@@ -129,7 +129,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
byte[] separator = STREAM_SEPARATORS.getOrDefault(mediaType, NEWLINE_SEPARATOR);
return Flux.from(inputStream).map(value -> {
DataBuffer buffer = encodeValue(
value, mimeType, bufferFactory, elementType, hints, encoding);
value, bufferFactory, elementType, mimeType, hints, encoding);
if (separator != null) {
buffer.write(separator);
}
@@ -139,13 +139,20 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
.orElseGet(() -> {
ResolvableType listType = ResolvableType.forClassWithGenerics(List.class, elementType);
return Flux.from(inputStream).collectList().map(list ->
encodeValue(list, mimeType, bufferFactory, listType, hints, encoding)).flux();
encodeValue(list, bufferFactory, listType, mimeType, hints, encoding)).flux();
});
}
}
private DataBuffer encodeValue(Object value, @Nullable MimeType mimeType, DataBufferFactory bufferFactory,
ResolvableType elementType, @Nullable Map<String, Object> hints, JsonEncoding encoding) {
@Override
public DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory,
ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
return encodeValue(value, bufferFactory, valueType, mimeType, hints, getJsonEncoding(mimeType));
}
private DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory, ResolvableType valueType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints, JsonEncoding encoding) {
if (!Hints.isLoggingSuppressed(hints)) {
LogFormatUtils.traceDebug(logger, traceOn -> {
@@ -154,7 +161,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
});
}
JavaType javaType = getJavaType(elementType.getType(), null);
JavaType javaType = getJavaType(valueType.getType(), null);
Class<?> jsonView = (hints != null ? (Class<?>) hints.get(Jackson2CodecSupport.JSON_VIEW_HINT) : null);
ObjectWriter writer = (jsonView != null ?
getObjectMapper().writerWithView(jsonView) : getObjectMapper().writer());
@@ -163,7 +170,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
writer = writer.forType(javaType);
}
writer = customizeWriter(writer, mimeType, elementType, hints);
writer = customizeWriter(writer, mimeType, valueType, hints);
DataBuffer buffer = bufferFactory.allocateBuffer();
boolean release = true;

View File

@@ -73,29 +73,39 @@ public class ProtobufEncoder extends ProtobufCodecSupport implements HttpMessage
public Flux<DataBuffer> encode(Publisher<? extends Message> inputStream, DataBufferFactory bufferFactory,
ResolvableType elementType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
return Flux.from(inputStream)
.map(message -> {
DataBuffer buffer = bufferFactory.allocateBuffer();
boolean release = true;
try {
if (!(inputStream instanceof Mono)) {
message.writeDelimitedTo(buffer.asOutputStream());
}
else {
message.writeTo(buffer.asOutputStream());
}
release = false;
return buffer;
}
catch (IOException ex) {
throw new IllegalStateException("Unexpected I/O error while writing to data buffer", ex);
}
finally {
if (release) {
DataBufferUtils.release(buffer);
}
}
});
return Flux.from(inputStream).map(message ->
encodeValue(message, bufferFactory, !(inputStream instanceof Mono)));
}
@Override
public DataBuffer encodeValue(Message message, DataBufferFactory bufferFactory,
ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
return encodeValue(message, bufferFactory, false);
}
private DataBuffer encodeValue(Message message, DataBufferFactory bufferFactory, boolean delimited) {
DataBuffer buffer = bufferFactory.allocateBuffer();
boolean release = true;
try {
if (delimited) {
message.writeDelimitedTo(buffer.asOutputStream());
}
else {
message.writeTo(buffer.asOutputStream());
}
release = false;
return buffer;
}
catch (IOException ex) {
throw new IllegalStateException("Unexpected I/O error while writing to data buffer", ex);
}
finally {
if (release) {
DataBufferUtils.release(buffer);
}
}
}
@Override

View File

@@ -99,7 +99,15 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> {
@Override
protected Flux<DataBuffer> encode(Object value, DataBufferFactory bufferFactory,
ResolvableType type, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
// we're relying on doOnDiscard in base class
return Mono.fromCallable(() -> encodeValue(value, bufferFactory, valueType, mimeType, hints)).flux();
}
@Override
public DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory,
ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
if (!Hints.isLoggingSuppressed(hints)) {
LogFormatUtils.traceDebug(logger, traceOn -> {
@@ -108,30 +116,27 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> {
});
}
return Flux.defer(() -> {
boolean release = true;
DataBuffer buffer = bufferFactory.allocateBuffer(1024);
try {
OutputStream outputStream = buffer.asOutputStream();
Class<?> clazz = ClassUtils.getUserClass(value);
Marshaller marshaller = initMarshaller(clazz);
marshaller.marshal(value, outputStream);
release = false;
return Mono.fromCallable(() -> buffer); // relying on doOnDiscard in base class
boolean release = true;
DataBuffer buffer = bufferFactory.allocateBuffer(1024);
try {
OutputStream outputStream = buffer.asOutputStream();
Class<?> clazz = ClassUtils.getUserClass(value);
Marshaller marshaller = initMarshaller(clazz);
marshaller.marshal(value, outputStream);
release = false;
return buffer;
}
catch (MarshalException ex) {
throw new EncodingException("Could not marshal " + value.getClass() + " to XML", ex);
}
catch (JAXBException ex) {
throw new CodecException("Invalid JAXB configuration", ex);
}
finally {
if (release) {
DataBufferUtils.release(buffer);
}
catch (MarshalException ex) {
return Flux.error(new EncodingException(
"Could not marshal " + value.getClass() + " to XML", ex));
}
catch (JAXBException ex) {
return Flux.error(new CodecException("Invalid JAXB configuration", ex));
}
finally {
if (release) {
DataBufferUtils.release(buffer);
}
}
});
}
}
private Marshaller initMarshaller(Class<?> clazz) throws JAXBException {