Add option to decode from a DataBuffer

See gh-22782
This commit is contained in:
Rossen Stoyanchev
2019-04-11 13:30:55 -04:00
parent 2aae81ef0c
commit a912d8de1e
10 changed files with 111 additions and 56 deletions

View File

@@ -45,6 +45,7 @@ import org.springframework.util.MimeType;
* @since 5.0
* @param <T> the element type
*/
@SuppressWarnings("deprecation")
public abstract class AbstractDataBufferDecoder<T> extends AbstractDecoder<T> {
@@ -70,8 +71,14 @@ public abstract class AbstractDataBufferDecoder<T> extends AbstractDecoder<T> {
/**
* How to decode a {@code DataBuffer} to the target element type.
* @deprecated as of 5.2, please implement
* {@link #decode(DataBuffer, ResolvableType, MimeType, Map)} instead
*/
protected abstract T decodeDataBuffer(DataBuffer buffer, ResolvableType elementType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints);
@Deprecated
protected T decodeDataBuffer(DataBuffer buffer, ResolvableType elementType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
return decode(buffer, elementType, mimeType, hints);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@@ -45,7 +45,7 @@ public class ByteArrayDecoder extends AbstractDataBufferDecoder<byte[]> {
}
@Override
protected byte[] decodeDataBuffer(DataBuffer dataBuffer, ResolvableType elementType,
public byte[] decode(DataBuffer dataBuffer, ResolvableType elementType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
byte[] result = new byte[dataBuffer.readableByteCount()];

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@@ -48,7 +48,7 @@ public class ByteBufferDecoder extends AbstractDataBufferDecoder<ByteBuffer> {
}
@Override
protected ByteBuffer decodeDataBuffer(DataBuffer dataBuffer, ResolvableType elementType,
public ByteBuffer decode(DataBuffer dataBuffer, ResolvableType elementType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
int byteCount = dataBuffer.readableByteCount();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@@ -64,7 +64,7 @@ public class DataBufferDecoder extends AbstractDataBufferDecoder<DataBuffer> {
}
@Override
protected DataBuffer decodeDataBuffer(DataBuffer buffer, ResolvableType elementType,
public DataBuffer decode(DataBuffer buffer, ResolvableType elementType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
if (logger.isDebugEnabled()) {

View File

@@ -22,10 +22,12 @@ import java.util.Map;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoProcessor;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
/**
@@ -75,6 +77,33 @@ public interface Decoder<T> {
Mono<T> decodeToMono(Publisher<DataBuffer> inputStream, ResolvableType elementType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints);
/**
* Decode a data buffer to an Object of type T. This is useful when the input
* stream consists of discrete messages (or events) and the content for each
* can be decoded on its own.
* @param buffer the {@code DataBuffer} to decode
* @param targetType the expected output type
* @param mimeType the MIME type associated with the data
* @param hints additional information about how to do encode
* @return the decoded value, possibly {@code null}
* @since 5.2
*/
@SuppressWarnings("ConstantConditions")
default T decode(DataBuffer buffer, ResolvableType targetType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) throws DecodingException {
MonoProcessor<T> processor = MonoProcessor.create();
decodeToMono(Mono.just(buffer), targetType, mimeType, hints).subscribeWith(processor);
Assert.state(processor.isTerminated(), "DataBuffer decoding should have completed.");
Throwable ex = processor.getError();
if (ex != null) {
throw (ex instanceof CodecException ? (CodecException) ex :
new DecodingException("Failed to decode: " + ex.getMessage(), ex));
}
return processor.peek();
}
/**
* Return the list of MIME types this decoder supports.
*/

View File

@@ -64,7 +64,7 @@ public class ResourceDecoder extends AbstractDataBufferDecoder<Resource> {
}
@Override
protected Resource decodeDataBuffer(DataBuffer dataBuffer, ResolvableType elementType,
public Resource decode(DataBuffer dataBuffer, ResolvableType elementType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
byte[] bytes = new byte[dataBuffer.readableByteCount()];

View File

@@ -202,7 +202,7 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
}
@Override
protected String decodeDataBuffer(DataBuffer dataBuffer, ResolvableType elementType,
public String decode(DataBuffer dataBuffer, ResolvableType elementType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
Charset charset = getCharset(mimeType);