parent
fa8f08391f
commit
9d65830133
|
@ -95,6 +95,8 @@ public interface ClientCodecConfigurer extends CodecConfigurer {
|
||||||
* <p>By default if this is not set, and Jackson is available, the
|
* <p>By default if this is not set, and Jackson is available, the
|
||||||
* {@link #jackson2JsonDecoder} override is used instead. Use this property
|
* {@link #jackson2JsonDecoder} override is used instead. Use this property
|
||||||
* if you want to further customize the SSE decoder.
|
* if you want to further customize the SSE decoder.
|
||||||
|
* <p>Note that {@link #maxInMemorySize(int)}, if configured, will be
|
||||||
|
* applied to the given decoder.
|
||||||
* @param decoder the decoder to use
|
* @param decoder the decoder to use
|
||||||
*/
|
*/
|
||||||
void serverSentEventDecoder(Decoder<?> decoder);
|
void serverSentEventDecoder(Decoder<?> decoder);
|
||||||
|
|
|
@ -109,6 +109,8 @@ public interface CodecConfigurer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the default Jackson JSON {@code Decoder}.
|
* Override the default Jackson JSON {@code Decoder}.
|
||||||
|
* <p>Note that {@link #maxInMemorySize(int)}, if configured, will be
|
||||||
|
* applied to the given decoder.
|
||||||
* @param decoder the decoder instance to use
|
* @param decoder the decoder instance to use
|
||||||
* @see org.springframework.http.codec.json.Jackson2JsonDecoder
|
* @see org.springframework.http.codec.json.Jackson2JsonDecoder
|
||||||
*/
|
*/
|
||||||
|
@ -123,6 +125,8 @@ public interface CodecConfigurer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the default Protobuf {@code Decoder}.
|
* Override the default Protobuf {@code Decoder}.
|
||||||
|
* <p>Note that {@link #maxInMemorySize(int)}, if configured, will be
|
||||||
|
* applied to the given decoder.
|
||||||
* @param decoder the decoder instance to use
|
* @param decoder the decoder instance to use
|
||||||
* @since 5.1
|
* @since 5.1
|
||||||
* @see org.springframework.http.codec.protobuf.ProtobufDecoder
|
* @see org.springframework.http.codec.protobuf.ProtobufDecoder
|
||||||
|
@ -140,6 +144,8 @@ public interface CodecConfigurer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the default JAXB2 {@code Decoder}.
|
* Override the default JAXB2 {@code Decoder}.
|
||||||
|
* <p>Note that {@link #maxInMemorySize(int)}, if configured, will be
|
||||||
|
* applied to the given decoder.
|
||||||
* @param decoder the decoder instance to use
|
* @param decoder the decoder instance to use
|
||||||
* @since 5.1.3
|
* @since 5.1.3
|
||||||
* @see org.springframework.http.codec.xml.Jaxb2XmlDecoder
|
* @see org.springframework.http.codec.xml.Jaxb2XmlDecoder
|
||||||
|
@ -245,7 +251,8 @@ public interface CodecConfigurer {
|
||||||
* Whether to log form data at DEBUG level, and headers at TRACE level.
|
* Whether to log form data at DEBUG level, and headers at TRACE level.
|
||||||
* Both may contain sensitive information.
|
* Both may contain sensitive information.
|
||||||
*/
|
*/
|
||||||
boolean isEnableLoggingRequestDetails();
|
@Nullable
|
||||||
|
Boolean isEnableLoggingRequestDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,9 @@ public interface ServerCodecConfigurer extends CodecConfigurer {
|
||||||
* MultipartHttpMessageReader} created with an instance of
|
* MultipartHttpMessageReader} created with an instance of
|
||||||
* {@link org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader
|
* {@link org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader
|
||||||
* SynchronossPartHttpMessageReader}.
|
* SynchronossPartHttpMessageReader}.
|
||||||
|
* <p>Note that {@link #maxInMemorySize(int)} and/or
|
||||||
|
* {@link #enableLoggingRequestDetails(boolean)}, if configured, will be
|
||||||
|
* applied to the given reader, if applicable.
|
||||||
* @param reader the message reader to use for multipart requests.
|
* @param reader the message reader to use for multipart requests.
|
||||||
* @since 5.1.11
|
* @since 5.1.11
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -149,6 +149,16 @@ public class MultipartHttpMessageWriter extends LoggingCodecSupport
|
||||||
return Collections.unmodifiableList(this.partWriters);
|
return Collections.unmodifiableList(this.partWriters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the configured form writer.
|
||||||
|
* @since 5.1.13
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public HttpMessageWriter<MultiValueMap<String, String>> getFormWriter() {
|
||||||
|
return this.formWriter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the character set to use for part headers such as
|
* Set the character set to use for part headers such as
|
||||||
* "Content-Disposition" (and its filename parameter).
|
* "Content-Disposition" (and its filename parameter).
|
||||||
|
|
|
@ -36,15 +36,20 @@ import org.springframework.http.codec.CodecConfigurer;
|
||||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||||
import org.springframework.http.codec.FormHttpMessageReader;
|
import org.springframework.http.codec.FormHttpMessageReader;
|
||||||
|
import org.springframework.http.codec.FormHttpMessageWriter;
|
||||||
import org.springframework.http.codec.HttpMessageReader;
|
import org.springframework.http.codec.HttpMessageReader;
|
||||||
import org.springframework.http.codec.HttpMessageWriter;
|
import org.springframework.http.codec.HttpMessageWriter;
|
||||||
import org.springframework.http.codec.ResourceHttpMessageReader;
|
import org.springframework.http.codec.ResourceHttpMessageReader;
|
||||||
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||||
|
import org.springframework.http.codec.ServerSentEventHttpMessageReader;
|
||||||
import org.springframework.http.codec.json.AbstractJackson2Decoder;
|
import org.springframework.http.codec.json.AbstractJackson2Decoder;
|
||||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||||
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
||||||
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
||||||
|
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
|
||||||
|
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
|
||||||
|
import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader;
|
||||||
import org.springframework.http.codec.protobuf.ProtobufDecoder;
|
import org.springframework.http.codec.protobuf.ProtobufDecoder;
|
||||||
import org.springframework.http.codec.protobuf.ProtobufEncoder;
|
import org.springframework.http.codec.protobuf.ProtobufEncoder;
|
||||||
import org.springframework.http.codec.protobuf.ProtobufHttpMessageWriter;
|
import org.springframework.http.codec.protobuf.ProtobufHttpMessageWriter;
|
||||||
|
@ -70,6 +75,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
|
|
||||||
private static final boolean protobufPresent;
|
private static final boolean protobufPresent;
|
||||||
|
|
||||||
|
static final boolean synchronossMultipartPresent;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ClassLoader classLoader = BaseCodecConfigurer.class.getClassLoader();
|
ClassLoader classLoader = BaseCodecConfigurer.class.getClassLoader();
|
||||||
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
|
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
|
||||||
|
@ -77,6 +84,7 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
|
jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
|
||||||
jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
|
jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
|
||||||
protobufPresent = ClassUtils.isPresent("com.google.protobuf.Message", classLoader);
|
protobufPresent = ClassUtils.isPresent("com.google.protobuf.Message", classLoader);
|
||||||
|
synchronossMultipartPresent = ClassUtils.isPresent("org.synchronoss.cloud.nio.multipart.NioMultipartParser", classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,7 +109,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
@Nullable
|
@Nullable
|
||||||
private Integer maxInMemorySize;
|
private Integer maxInMemorySize;
|
||||||
|
|
||||||
private boolean enableLoggingRequestDetails = false;
|
@Nullable
|
||||||
|
private Boolean enableLoggingRequestDetails;
|
||||||
|
|
||||||
private boolean registerDefaults = true;
|
private boolean registerDefaults = true;
|
||||||
|
|
||||||
|
@ -171,7 +180,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnableLoggingRequestDetails() {
|
@Nullable
|
||||||
|
public Boolean isEnableLoggingRequestDetails() {
|
||||||
return this.enableLoggingRequestDetails;
|
return this.enableLoggingRequestDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,48 +201,107 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
||||||
readers.add(new DecoderHttpMessageReader<>(init(new ByteArrayDecoder())));
|
addCodec(readers, new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
|
||||||
readers.add(new DecoderHttpMessageReader<>(init(new ByteBufferDecoder())));
|
addCodec(readers, new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
|
||||||
readers.add(new DecoderHttpMessageReader<>(init(new DataBufferDecoder())));
|
addCodec(readers, new DecoderHttpMessageReader<>(new DataBufferDecoder()));
|
||||||
readers.add(new ResourceHttpMessageReader(init(new ResourceDecoder())));
|
addCodec(readers, new ResourceHttpMessageReader(new ResourceDecoder()));
|
||||||
readers.add(new DecoderHttpMessageReader<>(init(StringDecoder.textPlainOnly())));
|
addCodec(readers, new DecoderHttpMessageReader<>(StringDecoder.textPlainOnly()));
|
||||||
if (protobufPresent) {
|
if (protobufPresent) {
|
||||||
Decoder<?> decoder = this.protobufDecoder != null ? this.protobufDecoder : init(new ProtobufDecoder());
|
Decoder<?> decoder = this.protobufDecoder != null ? this.protobufDecoder : new ProtobufDecoder();
|
||||||
readers.add(new DecoderHttpMessageReader<>(decoder));
|
addCodec(readers, new DecoderHttpMessageReader<>(decoder));
|
||||||
}
|
}
|
||||||
|
addCodec(readers, new FormHttpMessageReader());
|
||||||
|
|
||||||
FormHttpMessageReader formReader = new FormHttpMessageReader();
|
// client vs server..
|
||||||
if (this.maxInMemorySize != null) {
|
|
||||||
formReader.setMaxInMemorySize(this.maxInMemorySize);
|
|
||||||
}
|
|
||||||
formReader.setEnableLoggingRequestDetails(this.enableLoggingRequestDetails);
|
|
||||||
readers.add(formReader);
|
|
||||||
|
|
||||||
extendTypedReaders(readers);
|
extendTypedReaders(readers);
|
||||||
|
|
||||||
return readers;
|
return readers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends Decoder<?>> T init(T decoder) {
|
/**
|
||||||
if (this.maxInMemorySize != null) {
|
* Initialize a codec and add it to the List.
|
||||||
if (decoder instanceof AbstractDataBufferDecoder) {
|
* @since 5.1.13
|
||||||
((AbstractDataBufferDecoder<?>) decoder).setMaxInMemorySize(this.maxInMemorySize);
|
*/
|
||||||
|
protected <T> void addCodec(List<T> codecs, T codec) {
|
||||||
|
initCodec(codec);
|
||||||
|
codecs.add(codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply {@link #maxInMemorySize()} and {@link #enableLoggingRequestDetails},
|
||||||
|
* if configured by the application, to the given codec , including any
|
||||||
|
* codec it contains.
|
||||||
|
*/
|
||||||
|
private void initCodec(@Nullable Object codec) {
|
||||||
|
|
||||||
|
if (codec instanceof DecoderHttpMessageReader) {
|
||||||
|
codec = ((DecoderHttpMessageReader) codec).getDecoder();
|
||||||
|
}
|
||||||
|
else if (codec instanceof ServerSentEventHttpMessageReader) {
|
||||||
|
codec = ((ServerSentEventHttpMessageReader) codec).getDecoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codec == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer size = this.maxInMemorySize;
|
||||||
|
if (size != null) {
|
||||||
|
if (codec instanceof AbstractDataBufferDecoder) {
|
||||||
|
((AbstractDataBufferDecoder<?>) codec).setMaxInMemorySize(size);
|
||||||
}
|
}
|
||||||
if (decoder instanceof ProtobufDecoder) {
|
if (protobufPresent) {
|
||||||
((ProtobufDecoder) decoder).setMaxMessageSize(this.maxInMemorySize);
|
if (codec instanceof ProtobufDecoder) {
|
||||||
|
((ProtobufDecoder) codec).setMaxMessageSize(size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (jackson2Present) {
|
if (jackson2Present) {
|
||||||
if (decoder instanceof AbstractJackson2Decoder) {
|
if (codec instanceof AbstractJackson2Decoder) {
|
||||||
((AbstractJackson2Decoder) decoder).setMaxInMemorySize(this.maxInMemorySize);
|
((AbstractJackson2Decoder) codec).setMaxInMemorySize(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jaxb2Present) {
|
if (jaxb2Present) {
|
||||||
if (decoder instanceof Jaxb2XmlDecoder) {
|
if (codec instanceof Jaxb2XmlDecoder) {
|
||||||
((Jaxb2XmlDecoder) decoder).setMaxInMemorySize(this.maxInMemorySize);
|
((Jaxb2XmlDecoder) codec).setMaxInMemorySize(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (codec instanceof FormHttpMessageReader) {
|
||||||
|
((FormHttpMessageReader) codec).setMaxInMemorySize(size);
|
||||||
|
}
|
||||||
|
if (synchronossMultipartPresent) {
|
||||||
|
if (codec instanceof SynchronossPartHttpMessageReader) {
|
||||||
|
((SynchronossPartHttpMessageReader) codec).setMaxInMemorySize(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return decoder;
|
|
||||||
|
Boolean enable = this.enableLoggingRequestDetails;
|
||||||
|
if (enable != null) {
|
||||||
|
if (codec instanceof FormHttpMessageReader) {
|
||||||
|
((FormHttpMessageReader) codec).setEnableLoggingRequestDetails(enable);
|
||||||
|
}
|
||||||
|
if (codec instanceof MultipartHttpMessageReader) {
|
||||||
|
((MultipartHttpMessageReader) codec).setEnableLoggingRequestDetails(enable);
|
||||||
|
}
|
||||||
|
if (synchronossMultipartPresent) {
|
||||||
|
if (codec instanceof SynchronossPartHttpMessageReader) {
|
||||||
|
((SynchronossPartHttpMessageReader) codec).setEnableLoggingRequestDetails(enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (codec instanceof FormHttpMessageWriter) {
|
||||||
|
((FormHttpMessageWriter) codec).setEnableLoggingRequestDetails(enable);
|
||||||
|
}
|
||||||
|
if (codec instanceof MultipartHttpMessageWriter) {
|
||||||
|
((MultipartHttpMessageWriter) codec).setEnableLoggingRequestDetails(enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codec instanceof MultipartHttpMessageReader) {
|
||||||
|
initCodec(((MultipartHttpMessageReader) codec).getPartReader());
|
||||||
|
}
|
||||||
|
else if (codec instanceof MultipartHttpMessageWriter) {
|
||||||
|
initCodec(((MultipartHttpMessageWriter) codec).getFormWriter());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -250,16 +319,19 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
}
|
}
|
||||||
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
||||||
if (jackson2Present) {
|
if (jackson2Present) {
|
||||||
readers.add(new DecoderHttpMessageReader<>(init(getJackson2JsonDecoder())));
|
addCodec(readers, new DecoderHttpMessageReader<>(getJackson2JsonDecoder()));
|
||||||
}
|
}
|
||||||
if (jackson2SmilePresent) {
|
if (jackson2SmilePresent) {
|
||||||
readers.add(new DecoderHttpMessageReader<>(init(new Jackson2SmileDecoder())));
|
addCodec(readers, new DecoderHttpMessageReader<>(new Jackson2SmileDecoder()));
|
||||||
}
|
}
|
||||||
if (jaxb2Present) {
|
if (jaxb2Present) {
|
||||||
Decoder<?> decoder = this.jaxb2Decoder != null ? this.jaxb2Decoder : init(new Jaxb2XmlDecoder());
|
Decoder<?> decoder = this.jaxb2Decoder != null ? this.jaxb2Decoder : new Jaxb2XmlDecoder();
|
||||||
readers.add(new DecoderHttpMessageReader<>(decoder));
|
addCodec(readers, new DecoderHttpMessageReader<>(decoder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// client vs server..
|
||||||
extendObjectReaders(readers);
|
extendObjectReaders(readers);
|
||||||
|
|
||||||
return readers;
|
return readers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,9 +348,9 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
if (!this.registerDefaults) {
|
if (!this.registerDefaults) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
List<HttpMessageReader<?>> result = new ArrayList<>();
|
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
||||||
result.add(new DecoderHttpMessageReader<>(init(StringDecoder.allMimeTypes())));
|
addCodec(readers, new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes()));
|
||||||
return result;
|
return readers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -365,11 +437,17 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
// Accessors for use in subclasses...
|
// Accessors for use in subclasses...
|
||||||
|
|
||||||
protected Decoder<?> getJackson2JsonDecoder() {
|
protected Decoder<?> getJackson2JsonDecoder() {
|
||||||
return (this.jackson2JsonDecoder != null ? this.jackson2JsonDecoder : new Jackson2JsonDecoder());
|
if (this.jackson2JsonDecoder == null) {
|
||||||
|
this.jackson2JsonDecoder = new Jackson2JsonDecoder();
|
||||||
|
}
|
||||||
|
return this.jackson2JsonDecoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Encoder<?> getJackson2JsonEncoder() {
|
protected Encoder<?> getJackson2JsonEncoder() {
|
||||||
return (this.jackson2JsonEncoder != null ? this.jackson2JsonEncoder : new Jackson2JsonEncoder());
|
if (this.jackson2JsonEncoder == null) {
|
||||||
|
this.jackson2JsonEncoder = new Jackson2JsonEncoder();
|
||||||
|
}
|
||||||
|
return this.jackson2JsonEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,24 +95,17 @@ class ClientDefaultCodecsImpl extends BaseDefaultCodecs implements ClientCodecCo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void extendObjectReaders(List<HttpMessageReader<?>> objectReaders) {
|
protected void extendObjectReaders(List<HttpMessageReader<?>> objectReaders) {
|
||||||
objectReaders.add(new ServerSentEventHttpMessageReader(getSseDecoder()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
Decoder<?> decoder = (this.sseDecoder != null ?
|
||||||
private Decoder<?> getSseDecoder() {
|
this.sseDecoder :
|
||||||
return (this.sseDecoder != null ? this.sseDecoder : jackson2Present ? getJackson2JsonDecoder() : null);
|
jackson2Present ? getJackson2JsonDecoder() : null);
|
||||||
|
|
||||||
|
addCodec(objectReaders, new ServerSentEventHttpMessageReader(decoder));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void extendTypedWriters(List<HttpMessageWriter<?>> typedWriters) {
|
protected void extendTypedWriters(List<HttpMessageWriter<?>> typedWriters) {
|
||||||
|
addCodec(typedWriters, new MultipartHttpMessageWriter(getPartWriters(), new FormHttpMessageWriter()));
|
||||||
FormHttpMessageWriter formWriter = new FormHttpMessageWriter();
|
|
||||||
formWriter.setEnableLoggingRequestDetails(isEnableLoggingRequestDetails());
|
|
||||||
|
|
||||||
MultipartHttpMessageWriter multipartWriter = new MultipartHttpMessageWriter(getPartWriters(), formWriter);
|
|
||||||
multipartWriter.setEnableLoggingRequestDetails(isEnableLoggingRequestDetails());
|
|
||||||
|
|
||||||
typedWriters.add(multipartWriter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<HttpMessageWriter<?>> getPartWriters() {
|
private List<HttpMessageWriter<?>> getPartWriters() {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
|
||||||
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
|
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
|
||||||
import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader;
|
import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of {@link ServerCodecConfigurer.ServerDefaultCodecs}.
|
* Default implementation of {@link ServerCodecConfigurer.ServerDefaultCodecs}.
|
||||||
|
@ -34,11 +33,6 @@ import org.springframework.util.ClassUtils;
|
||||||
*/
|
*/
|
||||||
class ServerDefaultCodecsImpl extends BaseDefaultCodecs implements ServerCodecConfigurer.ServerDefaultCodecs {
|
class ServerDefaultCodecsImpl extends BaseDefaultCodecs implements ServerCodecConfigurer.ServerDefaultCodecs {
|
||||||
|
|
||||||
private static final boolean synchronossMultipartPresent =
|
|
||||||
ClassUtils.isPresent("org.synchronoss.cloud.nio.multipart.NioMultipartParser",
|
|
||||||
DefaultServerCodecConfigurer.class.getClassLoader());
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private HttpMessageReader<?> multipartReader;
|
private HttpMessageReader<?> multipartReader;
|
||||||
|
|
||||||
|
@ -70,23 +64,13 @@ class ServerDefaultCodecsImpl extends BaseDefaultCodecs implements ServerCodecCo
|
||||||
@Override
|
@Override
|
||||||
protected void extendTypedReaders(List<HttpMessageReader<?>> typedReaders) {
|
protected void extendTypedReaders(List<HttpMessageReader<?>> typedReaders) {
|
||||||
if (this.multipartReader != null) {
|
if (this.multipartReader != null) {
|
||||||
typedReaders.add(this.multipartReader);
|
addCodec(typedReaders, this.multipartReader);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (synchronossMultipartPresent) {
|
if (synchronossMultipartPresent) {
|
||||||
boolean enable = isEnableLoggingRequestDetails();
|
|
||||||
|
|
||||||
SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader();
|
SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader();
|
||||||
Integer size = maxInMemorySize();
|
addCodec(typedReaders, partReader);
|
||||||
if (size != null) {
|
addCodec(typedReaders, new MultipartHttpMessageReader(partReader));
|
||||||
partReader.setMaxInMemorySize(size);
|
|
||||||
}
|
|
||||||
partReader.setEnableLoggingRequestDetails(enable);
|
|
||||||
typedReaders.add(partReader);
|
|
||||||
|
|
||||||
MultipartHttpMessageReader reader = new MultipartHttpMessageReader(partReader);
|
|
||||||
reader.setEnableLoggingRequestDetails(enable);
|
|
||||||
typedReaders.add(reader);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
@ -37,6 +36,7 @@ import org.springframework.core.codec.DataBufferDecoder;
|
||||||
import org.springframework.core.codec.DataBufferEncoder;
|
import org.springframework.core.codec.DataBufferEncoder;
|
||||||
import org.springframework.core.codec.Decoder;
|
import org.springframework.core.codec.Decoder;
|
||||||
import org.springframework.core.codec.Encoder;
|
import org.springframework.core.codec.Encoder;
|
||||||
|
import org.springframework.core.codec.ResourceDecoder;
|
||||||
import org.springframework.core.codec.StringDecoder;
|
import org.springframework.core.codec.StringDecoder;
|
||||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
@ -44,6 +44,7 @@ import org.springframework.http.codec.ClientCodecConfigurer;
|
||||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||||
import org.springframework.http.codec.FormHttpMessageReader;
|
import org.springframework.http.codec.FormHttpMessageReader;
|
||||||
|
import org.springframework.http.codec.FormHttpMessageWriter;
|
||||||
import org.springframework.http.codec.HttpMessageReader;
|
import org.springframework.http.codec.HttpMessageReader;
|
||||||
import org.springframework.http.codec.HttpMessageWriter;
|
import org.springframework.http.codec.HttpMessageWriter;
|
||||||
import org.springframework.http.codec.ResourceHttpMessageReader;
|
import org.springframework.http.codec.ResourceHttpMessageReader;
|
||||||
|
@ -116,12 +117,45 @@ public class ClientCodecConfigurerTests {
|
||||||
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder();
|
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder();
|
||||||
this.configurer.defaultCodecs().jackson2JsonDecoder(decoder);
|
this.configurer.defaultCodecs().jackson2JsonDecoder(decoder);
|
||||||
|
|
||||||
assertThat(this.configurer.getReaders().stream()
|
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||||
.filter(reader -> ServerSentEventHttpMessageReader.class.equals(reader.getClass()))
|
assertThat(findCodec(readers, ServerSentEventHttpMessageReader.class).getDecoder()).isSameAs(decoder);
|
||||||
.map(reader -> (ServerSentEventHttpMessageReader) reader)
|
}
|
||||||
.findFirst()
|
|
||||||
.map(ServerSentEventHttpMessageReader::getDecoder)
|
@Test
|
||||||
.filter(e -> e == decoder).orElse(null)).isSameAs(decoder);
|
public void maxInMemorySize() {
|
||||||
|
int size = 99;
|
||||||
|
this.configurer.defaultCodecs().maxInMemorySize(size);
|
||||||
|
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||||
|
assertThat(readers.size()).isEqualTo(12);
|
||||||
|
assertThat(((ByteArrayDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
assertThat(((ByteBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
assertThat(((DataBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
assertThat(((ResourceDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
assertThat(((StringDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
assertThat(((ProtobufDecoder) getNextDecoder(readers)).getMaxMessageSize()).isEqualTo(size);
|
||||||
|
assertThat(((FormHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
|
||||||
|
assertThat(((Jackson2JsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
assertThat(((Jackson2SmileDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
assertThat(((Jaxb2XmlDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
|
||||||
|
ServerSentEventHttpMessageReader reader = (ServerSentEventHttpMessageReader) nextReader(readers);
|
||||||
|
assertThat(((Jackson2JsonDecoder) reader.getDecoder()).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
|
||||||
|
assertThat(((StringDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void enableLoggingRequestDetails() {
|
||||||
|
this.configurer.defaultCodecs().enableLoggingRequestDetails(true);
|
||||||
|
|
||||||
|
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
||||||
|
MultipartHttpMessageWriter multipartWriter = findCodec(writers, MultipartHttpMessageWriter.class);
|
||||||
|
assertThat(multipartWriter.isEnableLoggingRequestDetails()).isTrue();
|
||||||
|
|
||||||
|
FormHttpMessageWriter formWriter = (FormHttpMessageWriter) multipartWriter.getFormWriter();
|
||||||
|
assertThat(formWriter).isNotNull();
|
||||||
|
assertThat(formWriter.isEnableLoggingRequestDetails()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -135,49 +169,42 @@ public class ClientCodecConfigurerTests {
|
||||||
|
|
||||||
// Clone has the customizations
|
// Clone has the customizations
|
||||||
|
|
||||||
Decoder<?> sseDecoder = clone.getReaders().stream()
|
Decoder<?> sseDecoder = findCodec(clone.getReaders(), ServerSentEventHttpMessageReader.class).getDecoder();
|
||||||
.filter(reader -> reader instanceof ServerSentEventHttpMessageReader)
|
List<HttpMessageWriter<?>> writers = findCodec(clone.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
||||||
.map(reader -> ((ServerSentEventHttpMessageReader) reader).getDecoder())
|
|
||||||
.findFirst()
|
|
||||||
.get();
|
|
||||||
|
|
||||||
List<HttpMessageWriter<?>> multipartWriters = clone.getWriters().stream()
|
|
||||||
.filter(writer -> writer instanceof MultipartHttpMessageWriter)
|
|
||||||
.flatMap(writer -> ((MultipartHttpMessageWriter) writer).getPartWriters().stream())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
assertThat(sseDecoder).isSameAs(jackson2Decoder);
|
assertThat(sseDecoder).isSameAs(jackson2Decoder);
|
||||||
assertThat(multipartWriters).hasSize(2);
|
assertThat(writers).hasSize(2);
|
||||||
|
|
||||||
// Original does not have the customizations
|
// Original does not have the customizations
|
||||||
|
|
||||||
sseDecoder = this.configurer.getReaders().stream()
|
sseDecoder = findCodec(this.configurer.getReaders(), ServerSentEventHttpMessageReader.class).getDecoder();
|
||||||
.filter(reader -> reader instanceof ServerSentEventHttpMessageReader)
|
writers = findCodec(this.configurer.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
||||||
.map(reader -> ((ServerSentEventHttpMessageReader) reader).getDecoder())
|
|
||||||
.findFirst()
|
|
||||||
.get();
|
|
||||||
|
|
||||||
multipartWriters = this.configurer.getWriters().stream()
|
|
||||||
.filter(writer -> writer instanceof MultipartHttpMessageWriter)
|
|
||||||
.flatMap(writer -> ((MultipartHttpMessageWriter) writer).getPartWriters().stream())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
assertThat(sseDecoder).isNotSameAs(jackson2Decoder);
|
assertThat(sseDecoder).isNotSameAs(jackson2Decoder);
|
||||||
assertThat(multipartWriters).hasSize(10);
|
assertThat(writers).hasSize(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Decoder<?> getNextDecoder(List<HttpMessageReader<?>> readers) {
|
private Decoder<?> getNextDecoder(List<HttpMessageReader<?>> readers) {
|
||||||
HttpMessageReader<?> reader = readers.get(this.index.getAndIncrement());
|
HttpMessageReader<?> reader = readers.get(this.index.getAndIncrement());
|
||||||
assertThat(reader.getClass()).isEqualTo(DecoderHttpMessageReader.class);
|
assertThat(reader).isInstanceOf(DecoderHttpMessageReader.class);
|
||||||
return ((DecoderHttpMessageReader<?>) reader).getDecoder();
|
return ((DecoderHttpMessageReader<?>) reader).getDecoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HttpMessageReader<?> nextReader(List<HttpMessageReader<?>> readers) {
|
||||||
|
return readers.get(this.index.getAndIncrement());
|
||||||
|
}
|
||||||
|
|
||||||
private Encoder<?> getNextEncoder(List<HttpMessageWriter<?>> writers) {
|
private Encoder<?> getNextEncoder(List<HttpMessageWriter<?>> writers) {
|
||||||
HttpMessageWriter<?> writer = writers.get(this.index.getAndIncrement());
|
HttpMessageWriter<?> writer = writers.get(this.index.getAndIncrement());
|
||||||
assertThat(writer.getClass()).isEqualTo(EncoderHttpMessageWriter.class);
|
assertThat(writer.getClass()).isEqualTo(EncoderHttpMessageWriter.class);
|
||||||
return ((EncoderHttpMessageWriter<?>) writer).getEncoder();
|
return ((EncoderHttpMessageWriter<?>) writer).getEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> T findCodec(List<?> codecs, Class<T> type) {
|
||||||
|
return (T) codecs.stream().filter(type::isInstance).findFirst().get();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void assertStringDecoder(Decoder<?> decoder, boolean textOnly) {
|
private void assertStringDecoder(Decoder<?> decoder, boolean textOnly) {
|
||||||
assertThat(decoder.getClass()).isEqualTo(StringDecoder.class);
|
assertThat(decoder.getClass()).isEqualTo(StringDecoder.class);
|
||||||
|
|
|
@ -134,11 +134,7 @@ public class ServerCodecConfigurerTests {
|
||||||
assertThat(((ByteArrayDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((ByteArrayDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((ByteBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((ByteBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((DataBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((DataBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
assertThat(((ResourceDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
ResourceHttpMessageReader resourceReader = (ResourceHttpMessageReader) nextReader(readers);
|
|
||||||
ResourceDecoder decoder = (ResourceDecoder) resourceReader.getDecoder();
|
|
||||||
assertThat(decoder.getMaxInMemorySize()).isEqualTo(size);
|
|
||||||
|
|
||||||
assertThat(((StringDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((StringDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((ProtobufDecoder) getNextDecoder(readers)).getMaxMessageSize()).isEqualTo(size);
|
assertThat(((ProtobufDecoder) getNextDecoder(readers)).getMaxMessageSize()).isEqualTo(size);
|
||||||
assertThat(((FormHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((FormHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
@ -154,6 +150,20 @@ public class ServerCodecConfigurerTests {
|
||||||
assertThat(((StringDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((StringDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void enableRequestLoggingDetails() {
|
||||||
|
this.configurer.defaultCodecs().enableLoggingRequestDetails(true);
|
||||||
|
|
||||||
|
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||||
|
assertThat(findCodec(readers, FormHttpMessageReader.class).isEnableLoggingRequestDetails()).isTrue();
|
||||||
|
|
||||||
|
MultipartHttpMessageReader multipartReader = findCodec(readers, MultipartHttpMessageReader.class);
|
||||||
|
assertThat(multipartReader.isEnableLoggingRequestDetails()).isTrue();
|
||||||
|
|
||||||
|
SynchronossPartHttpMessageReader reader = (SynchronossPartHttpMessageReader) multipartReader.getPartReader();
|
||||||
|
assertThat(reader.isEnableLoggingRequestDetails()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void cloneConfigurer() {
|
public void cloneConfigurer() {
|
||||||
ServerCodecConfigurer clone = this.configurer.clone();
|
ServerCodecConfigurer clone = this.configurer.clone();
|
||||||
|
@ -165,42 +175,27 @@ public class ServerCodecConfigurerTests {
|
||||||
|
|
||||||
// Clone has the customizations
|
// Clone has the customizations
|
||||||
|
|
||||||
HttpMessageReader<?> actualReader = clone.getReaders().stream()
|
HttpMessageReader<?> actualReader =
|
||||||
.filter(r -> r instanceof MultipartHttpMessageReader)
|
findCodec(clone.getReaders(), MultipartHttpMessageReader.class);
|
||||||
.findFirst()
|
|
||||||
.get();
|
|
||||||
|
|
||||||
Encoder<?> actualEncoder = clone.getWriters().stream()
|
|
||||||
.filter(writer -> writer instanceof ServerSentEventHttpMessageWriter)
|
|
||||||
.map(writer -> ((ServerSentEventHttpMessageWriter) writer).getEncoder())
|
|
||||||
.findFirst()
|
|
||||||
.get();
|
|
||||||
|
|
||||||
|
ServerSentEventHttpMessageWriter actualWriter =
|
||||||
|
findCodec(clone.getWriters(), ServerSentEventHttpMessageWriter.class);
|
||||||
|
|
||||||
assertThat(actualReader).isSameAs(reader);
|
assertThat(actualReader).isSameAs(reader);
|
||||||
assertThat(actualEncoder).isSameAs(encoder);
|
assertThat(actualWriter.getEncoder()).isSameAs(encoder);
|
||||||
|
|
||||||
// Original does not have the customizations
|
// Original does not have the customizations
|
||||||
|
|
||||||
actualReader = this.configurer.getReaders().stream()
|
actualReader = findCodec(this.configurer.getReaders(), MultipartHttpMessageReader.class);
|
||||||
.filter(r -> r instanceof MultipartHttpMessageReader)
|
actualWriter = findCodec(this.configurer.getWriters(), ServerSentEventHttpMessageWriter.class);
|
||||||
.findFirst()
|
|
||||||
.get();
|
|
||||||
|
|
||||||
actualEncoder = this.configurer.getWriters().stream()
|
|
||||||
.filter(writer -> writer instanceof ServerSentEventHttpMessageWriter)
|
|
||||||
.map(writer -> ((ServerSentEventHttpMessageWriter) writer).getEncoder())
|
|
||||||
.findFirst()
|
|
||||||
.get();
|
|
||||||
|
|
||||||
|
|
||||||
assertThat(actualReader).isNotSameAs(reader);
|
assertThat(actualReader).isNotSameAs(reader);
|
||||||
assertThat(actualEncoder).isNotSameAs(encoder);
|
assertThat(actualWriter.getEncoder()).isNotSameAs(encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Decoder<?> getNextDecoder(List<HttpMessageReader<?>> readers) {
|
private Decoder<?> getNextDecoder(List<HttpMessageReader<?>> readers) {
|
||||||
HttpMessageReader<?> reader = nextReader(readers);
|
HttpMessageReader<?> reader = nextReader(readers);
|
||||||
assertThat(reader.getClass()).isEqualTo(DecoderHttpMessageReader.class);
|
assertThat(reader).isInstanceOf(DecoderHttpMessageReader.class);
|
||||||
return ((DecoderHttpMessageReader<?>) reader).getDecoder();
|
return ((DecoderHttpMessageReader<?>) reader).getDecoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +209,11 @@ public class ServerCodecConfigurerTests {
|
||||||
return ((EncoderHttpMessageWriter<?>) writer).getEncoder();
|
return ((EncoderHttpMessageWriter<?>) writer).getEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> T findCodec(List<?> codecs, Class<T> type) {
|
||||||
|
return (T) codecs.stream().filter(type::isInstance).findFirst().get();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void assertStringDecoder(Decoder<?> decoder, boolean textOnly) {
|
private void assertStringDecoder(Decoder<?> decoder, boolean textOnly) {
|
||||||
assertThat(decoder.getClass()).isEqualTo(StringDecoder.class);
|
assertThat(decoder.getClass()).isEqualTo(StringDecoder.class);
|
||||||
|
|
Loading…
Reference in New Issue