Browse Source

Change default codecs ordering and add Jackson CBOR

This commit updates BaseDefaultCodecs by adding Kotlin
Serialization codecs before their Jackson/GSON counterparts
with their new default behavior that only handles classes with
`@Serializable` at type or generics level.

When there is no alternative codec for the same mime type,
Kotlin Serialization codecs handle all supported cases.

This commit also adds missing Jackson CBOR codecs, and moves both
CBOR and Protobuf codecs to a lower priority, as they are less
commonly used than JSON ones, with the same ordering used on
Spring MVC side.

See gh-35761
Closes gh-35787
pull/34993/merge
Sébastien Deleuze 1 month ago
parent
commit
d0f57013b0
  1. 18
      spring-web/src/main/java/org/springframework/http/codec/CodecConfigurer.java
  2. 157
      spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java
  3. 34
      spring-web/src/test/java/org/springframework/http/codec/support/ClientCodecConfigurerTests.java
  4. 36
      spring-web/src/test/java/org/springframework/http/codec/support/CodecConfigurerTests.java
  5. 26
      spring-web/src/test/java/org/springframework/http/codec/support/ServerCodecConfigurerTests.java
  6. 2
      spring-webflux/src/test/java/org/springframework/web/reactive/config/DelegatingWebFluxConfigurationTests.java

18
spring-web/src/main/java/org/springframework/http/codec/CodecConfigurer.java

@ -208,6 +208,24 @@ public interface CodecConfigurer { @@ -208,6 +208,24 @@ public interface CodecConfigurer {
jacksonSmileEncoder(encoder);
}
/**
* Override the default Jackson 3.x CBOR {@code Decoder}.
* <p>Note that {@link #maxInMemorySize(int)}, if configured, will be
* applied to the given decoder.
* @param decoder the decoder instance to use
* @since 7.0
* @see org.springframework.http.codec.cbor.JacksonCborDecoder
*/
void jacksonCborDecoder(Decoder<?> decoder);
/**
* Override the default Jackson 3.x CBOR {@code Encoder}.
* @param encoder the encoder instance to use
* @since 7.0
* @see org.springframework.http.codec.cbor.JacksonCborEncoder
*/
void jacksonCborEncoder(Encoder<?> encoder);
/**
* Override the default Protobuf {@code Decoder}.
* <p>Note that {@link #maxInMemorySize(int)}, if configured, will be

157
spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java

@ -51,6 +51,10 @@ import org.springframework.http.codec.ResourceHttpMessageReader; @@ -51,6 +51,10 @@ import org.springframework.http.codec.ResourceHttpMessageReader;
import org.springframework.http.codec.ResourceHttpMessageWriter;
import org.springframework.http.codec.ServerSentEventHttpMessageReader;
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
import org.springframework.http.codec.cbor.Jackson2CborDecoder;
import org.springframework.http.codec.cbor.Jackson2CborEncoder;
import org.springframework.http.codec.cbor.JacksonCborDecoder;
import org.springframework.http.codec.cbor.JacksonCborEncoder;
import org.springframework.http.codec.cbor.KotlinSerializationCborDecoder;
import org.springframework.http.codec.cbor.KotlinSerializationCborEncoder;
import org.springframework.http.codec.json.AbstractJackson2Decoder;
@ -101,6 +105,10 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -101,6 +105,10 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
private static final boolean JACKSON_2_SMILE_PRESENT;
private static final boolean JACKSON_CBOR_PRESENT;
private static final boolean JACKSON_2_CBOR_PRESENT;
private static final boolean JAXB_2_PRESENT;
private static final boolean PROTOBUF_PRESENT;
@ -121,6 +129,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -121,6 +129,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
GSON_PRESENT = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
JACKSON_SMILE_PRESENT = JACKSON_PRESENT && ClassUtils.isPresent("tools.jackson.dataformat.smile.SmileMapper", classLoader);
JACKSON_2_SMILE_PRESENT = JACKSON_2_PRESENT && ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
JACKSON_CBOR_PRESENT = JACKSON_PRESENT && ClassUtils.isPresent("tools.jackson.dataformat.cbor.CBORMapper", classLoader);
JACKSON_2_CBOR_PRESENT = JACKSON_2_PRESENT && ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper", classLoader);
JAXB_2_PRESENT = ClassUtils.isPresent("jakarta.xml.bind.Binder", classLoader);
PROTOBUF_PRESENT = ClassUtils.isPresent("com.google.protobuf.Message", classLoader);
NETTY_BYTE_BUF_PRESENT = ClassUtils.isPresent("io.netty.buffer.ByteBuf", classLoader);
@ -142,6 +152,10 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -142,6 +152,10 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
private @Nullable Decoder<?> jacksonSmileDecoder;
private @Nullable Encoder<?> jacksonCborEncoder;
private @Nullable Decoder<?> jacksonCborDecoder;
private @Nullable Decoder<?> protobufDecoder;
private @Nullable Encoder<?> protobufEncoder;
@ -221,6 +235,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -221,6 +235,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
this.gsonEncoder = other.gsonEncoder;
this.jacksonSmileDecoder = other.jacksonSmileDecoder;
this.jacksonSmileEncoder = other.jacksonSmileEncoder;
this.jacksonCborDecoder = other.jacksonCborDecoder;
this.jacksonCborEncoder = other.jacksonCborEncoder;
this.protobufDecoder = other.protobufDecoder;
this.protobufEncoder = other.protobufEncoder;
this.jaxb2Decoder = other.jaxb2Decoder;
@ -283,6 +299,19 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -283,6 +299,19 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
initTypedWriters();
}
@Override
public void jacksonCborDecoder(Decoder<?> decoder) {
this.jacksonCborDecoder = decoder;
initObjectReaders();
}
@Override
public void jacksonCborEncoder(Encoder<?> encoder) {
this.jacksonCborEncoder = encoder;
initObjectWriters();
initTypedWriters();
}
@Override
public void protobufDecoder(Decoder<?> decoder) {
this.protobufDecoder = decoder;
@ -604,16 +633,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -604,16 +633,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
if (!this.registerDefaults) {
return;
}
if (KOTLIN_SERIALIZATION_CBOR_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(this.kotlinSerializationCborDecoder != null ?
(KotlinSerializationCborDecoder) this.kotlinSerializationCborDecoder :
new KotlinSerializationCborDecoder()));
}
if (KOTLIN_SERIALIZATION_PROTOBUF_PRESENT) {
addCodec(this.objectReaders,
new DecoderHttpMessageReader<>(this.kotlinSerializationProtobufDecoder != null ?
(KotlinSerializationProtobufDecoder) this.kotlinSerializationProtobufDecoder :
new KotlinSerializationProtobufDecoder()));
if (KOTLIN_SERIALIZATION_JSON_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getKotlinSerializationJsonDecoder()));
}
if (JACKSON_PRESENT || JACKSON_2_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getJacksonJsonDecoder()));
@ -621,16 +642,23 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -621,16 +642,23 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
else if (GSON_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getGsonDecoder()));
}
else if (KOTLIN_SERIALIZATION_JSON_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getKotlinSerializationJsonDecoder()));
}
if (JACKSON_SMILE_PRESENT || JACKSON_2_SMILE_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getJacksonSmileDecoder()));
}
if (KOTLIN_SERIALIZATION_CBOR_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getKotlinSerializationCborDecoder()));
}
if (JACKSON_CBOR_PRESENT || JACKSON_2_CBOR_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getJacksonCborDecoder()));
}
if (JAXB_2_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(this.jaxb2Decoder != null ?
(Jaxb2XmlDecoder) this.jaxb2Decoder : new Jaxb2XmlDecoder()));
}
if (KOTLIN_SERIALIZATION_PROTOBUF_PRESENT) {
addCodec(this.objectReaders,
new DecoderHttpMessageReader<>(getKotlinSerializationProtobufDecoder()));
}
// client vs server..
extendObjectReaders(this.objectReaders);
@ -744,15 +772,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -744,15 +772,8 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
*/
final List<HttpMessageWriter<?>> getBaseObjectWriters() {
List<HttpMessageWriter<?>> writers = new ArrayList<>();
if (KOTLIN_SERIALIZATION_CBOR_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(this.kotlinSerializationCborEncoder != null ?
(KotlinSerializationCborEncoder) this.kotlinSerializationCborEncoder :
new KotlinSerializationCborEncoder()));
}
if (KOTLIN_SERIALIZATION_PROTOBUF_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(this.kotlinSerializationProtobufEncoder != null ?
(KotlinSerializationProtobufEncoder) this.kotlinSerializationProtobufEncoder :
new KotlinSerializationProtobufEncoder()));
if (KOTLIN_SERIALIZATION_JSON_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getKotlinSerializationJsonEncoder()));
}
if (JACKSON_PRESENT || JACKSON_2_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getJacksonJsonEncoder()));
@ -760,16 +781,22 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -760,16 +781,22 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
else if (GSON_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getGsonEncoder()));
}
else if (KOTLIN_SERIALIZATION_JSON_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getKotlinSerializationJsonEncoder()));
}
if (JACKSON_SMILE_PRESENT || JACKSON_2_SMILE_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getJacksonSmileEncoder()));
}
if (KOTLIN_SERIALIZATION_CBOR_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getKotlinSerializationCborEncoder()));
}
if (JACKSON_CBOR_PRESENT || JACKSON_2_CBOR_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getJacksonCborEncoder()));
}
if (JAXB_2_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(this.jaxb2Encoder != null ?
(Jaxb2XmlEncoder) this.jaxb2Encoder : new Jaxb2XmlEncoder()));
}
if (KOTLIN_SERIALIZATION_PROTOBUF_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getKotlinSerializationProtobufEncoder()));
}
return writers;
}
@ -876,14 +903,14 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -876,14 +903,14 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
@SuppressWarnings("removal")
protected Decoder<?> getJacksonSmileDecoder() {
if (this.jacksonSmileDecoder == null) {
if (JACKSON_PRESENT) {
if (JACKSON_SMILE_PRESENT) {
this.jacksonSmileDecoder = new JacksonSmileDecoder();
}
else if (JACKSON_2_PRESENT) {
else if (JACKSON_2_SMILE_PRESENT) {
this.jacksonSmileDecoder = new Jackson2SmileDecoder();
}
else {
throw new IllegalStateException("Jackson not present");
throw new IllegalStateException("Jackson Smile support not present");
}
}
return this.jacksonSmileDecoder;
@ -892,33 +919,97 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure @@ -892,33 +919,97 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
@SuppressWarnings("removal")
protected Encoder<?> getJacksonSmileEncoder() {
if (this.jacksonSmileEncoder == null) {
if (JACKSON_PRESENT) {
if (JACKSON_SMILE_PRESENT) {
this.jacksonSmileEncoder = new JacksonSmileEncoder();
}
else if (JACKSON_2_PRESENT) {
else if (JACKSON_2_SMILE_PRESENT) {
this.jacksonSmileEncoder = new Jackson2SmileEncoder();
}
else {
throw new IllegalStateException("Jackson not present");
throw new IllegalStateException("Jackson Smile support not present");
}
}
return this.jacksonSmileEncoder;
}
@SuppressWarnings("removal")
protected Decoder<?> getJacksonCborDecoder() {
if (this.jacksonCborDecoder == null) {
if (JACKSON_CBOR_PRESENT) {
this.jacksonCborDecoder = new JacksonCborDecoder();
}
else if (JACKSON_2_CBOR_PRESENT) {
this.jacksonCborDecoder = new Jackson2CborDecoder();
}
else {
throw new IllegalStateException("Jackson CBOR support not present");
}
}
return this.jacksonCborDecoder;
}
@SuppressWarnings("removal")
protected Encoder<?> getJacksonCborEncoder() {
if (this.jacksonCborEncoder == null) {
if (JACKSON_CBOR_PRESENT) {
this.jacksonCborEncoder = new JacksonCborEncoder();
}
else if (JACKSON_2_CBOR_PRESENT) {
this.jacksonCborEncoder = new Jackson2CborEncoder();
}
else {
throw new IllegalStateException("Jackson CBOR support not present");
}
}
return this.jacksonCborEncoder;
}
protected Decoder<?> getKotlinSerializationJsonDecoder() {
if (this.kotlinSerializationJsonDecoder == null) {
this.kotlinSerializationJsonDecoder = new KotlinSerializationJsonDecoder();
this.kotlinSerializationJsonDecoder = (this.jacksonJsonDecoder != null || JACKSON_PRESENT || JACKSON_2_PRESENT || GSON_PRESENT ?
new KotlinSerializationJsonDecoder() : new KotlinSerializationJsonDecoder(type -> true));
}
return this.kotlinSerializationJsonDecoder;
}
protected Encoder<?> getKotlinSerializationJsonEncoder() {
if (this.kotlinSerializationJsonEncoder == null) {
this.kotlinSerializationJsonEncoder = new KotlinSerializationJsonEncoder();
this.kotlinSerializationJsonEncoder = (this.jacksonJsonDecoder != null || JACKSON_PRESENT || JACKSON_2_PRESENT || GSON_PRESENT ?
new KotlinSerializationJsonEncoder() : new KotlinSerializationJsonEncoder(type -> true));
}
return this.kotlinSerializationJsonEncoder;
}
protected Decoder<?> getKotlinSerializationCborDecoder() {
if (this.kotlinSerializationCborDecoder == null) {
this.kotlinSerializationCborDecoder = (this.jacksonCborDecoder != null || JACKSON_CBOR_PRESENT ?
new KotlinSerializationCborDecoder() : new KotlinSerializationCborDecoder(type -> true));
}
return this.kotlinSerializationCborDecoder;
}
protected Encoder<?> getKotlinSerializationCborEncoder() {
if (this.kotlinSerializationCborEncoder == null) {
this.kotlinSerializationCborEncoder = (this.jacksonCborDecoder != null || JACKSON_CBOR_PRESENT ?
new KotlinSerializationCborEncoder() : new KotlinSerializationCborEncoder(type -> true));
}
return this.kotlinSerializationCborEncoder;
}
protected Decoder<?> getKotlinSerializationProtobufDecoder() {
if (this.kotlinSerializationProtobufDecoder == null) {
this.kotlinSerializationProtobufDecoder = new KotlinSerializationProtobufDecoder(type -> true);
}
return this.kotlinSerializationProtobufDecoder;
}
protected Encoder<?> getKotlinSerializationProtobufEncoder() {
if (this.kotlinSerializationProtobufEncoder == null) {
this.kotlinSerializationProtobufEncoder = new KotlinSerializationProtobufEncoder(type -> true);
}
return this.kotlinSerializationProtobufEncoder;
}
/**
* Default implementation of {@link CodecConfigurer.MultipartCodecs}.

34
spring-web/src/test/java/org/springframework/http/codec/support/ClientCodecConfigurerTests.java

@ -52,10 +52,14 @@ import org.springframework.http.codec.HttpMessageWriter; @@ -52,10 +52,14 @@ import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.codec.ResourceHttpMessageReader;
import org.springframework.http.codec.ResourceHttpMessageWriter;
import org.springframework.http.codec.ServerSentEventHttpMessageReader;
import org.springframework.http.codec.cbor.JacksonCborDecoder;
import org.springframework.http.codec.cbor.JacksonCborEncoder;
import org.springframework.http.codec.cbor.KotlinSerializationCborDecoder;
import org.springframework.http.codec.cbor.KotlinSerializationCborEncoder;
import org.springframework.http.codec.json.JacksonJsonDecoder;
import org.springframework.http.codec.json.JacksonJsonEncoder;
import org.springframework.http.codec.json.KotlinSerializationJsonDecoder;
import org.springframework.http.codec.json.KotlinSerializationJsonEncoder;
import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader;
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
@ -91,7 +95,7 @@ class ClientCodecConfigurerTests { @@ -91,7 +95,7 @@ class ClientCodecConfigurerTests {
@Test
void defaultReaders() {
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
assertThat(readers).hasSize(18);
assertThat(readers).hasSize(20);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
@ -104,11 +108,13 @@ class ClientCodecConfigurerTests { @@ -104,11 +108,13 @@ class ClientCodecConfigurerTests {
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(DefaultPartHttpMessageReader.class);
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageReader.class);
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartEventHttpMessageReader.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationJsonDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonJsonDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonSmileDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
assertSseReader(readers);
assertStringDecoder(getNextDecoder(readers), false);
}
@ -116,7 +122,7 @@ class ClientCodecConfigurerTests { @@ -116,7 +122,7 @@ class ClientCodecConfigurerTests {
@Test
void defaultWriters() {
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
assertThat(writers).hasSize(16);
assertThat(writers).hasSize(18);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
@ -127,11 +133,13 @@ class ClientCodecConfigurerTests { @@ -127,11 +133,13 @@ class ClientCodecConfigurerTests {
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageWriter.class);
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartEventHttpMessageWriter.class);
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartHttpMessageWriter.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationJsonEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonJsonEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonSmileEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
assertStringEncoder(getNextEncoder(writers), false);
}
@ -161,7 +169,7 @@ class ClientCodecConfigurerTests { @@ -161,7 +169,7 @@ class ClientCodecConfigurerTests {
int size = 99;
this.configurer.defaultCodecs().maxInMemorySize(size);
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
assertThat(readers).hasSize(18);
assertThat(readers).hasSize(20);
assertThat(((ByteArrayDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((ByteBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((DataBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
@ -173,11 +181,13 @@ class ClientCodecConfigurerTests { @@ -173,11 +181,13 @@ class ClientCodecConfigurerTests {
assertThat(((DefaultPartHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
nextReader(readers);
assertThat(((PartEventHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationCborDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationProtobufDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationJsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((JacksonJsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((JacksonSmileDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationCborDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((JacksonCborDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((Jaxb2XmlDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationProtobufDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
ServerSentEventHttpMessageReader reader = (ServerSentEventHttpMessageReader) nextReader(readers);
assertThat(reader.getMaxInMemorySize()).isEqualTo(size);
@ -222,7 +232,7 @@ class ClientCodecConfigurerTests { @@ -222,7 +232,7 @@ class ClientCodecConfigurerTests {
writers = findCodec(this.configurer.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
assertThat(sseDecoder).isNotSameAs(jacksonDecoder);
assertThat(writers).hasSize(16);
assertThat(writers).hasSize(18);
}
@Test // gh-24194
@ -232,7 +242,7 @@ class ClientCodecConfigurerTests { @@ -232,7 +242,7 @@ class ClientCodecConfigurerTests {
List<HttpMessageWriter<?>> writers =
findCodec(clone.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
assertThat(writers).hasSize(16);
assertThat(writers).hasSize(18);
}
@Test
@ -246,7 +256,7 @@ class ClientCodecConfigurerTests { @@ -246,7 +256,7 @@ class ClientCodecConfigurerTests {
List<HttpMessageWriter<?>> writers =
findCodec(clone.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
assertThat(writers).hasSize(16);
assertThat(writers).hasSize(18);
}
private Decoder<?> getNextDecoder(List<HttpMessageReader<?>> readers) {

36
spring-web/src/test/java/org/springframework/http/codec/support/CodecConfigurerTests.java

@ -47,10 +47,14 @@ import org.springframework.http.codec.ResourceHttpMessageReader; @@ -47,10 +47,14 @@ import org.springframework.http.codec.ResourceHttpMessageReader;
import org.springframework.http.codec.ResourceHttpMessageWriter;
import org.springframework.http.codec.ServerSentEventHttpMessageReader;
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
import org.springframework.http.codec.cbor.JacksonCborDecoder;
import org.springframework.http.codec.cbor.JacksonCborEncoder;
import org.springframework.http.codec.cbor.KotlinSerializationCborDecoder;
import org.springframework.http.codec.cbor.KotlinSerializationCborEncoder;
import org.springframework.http.codec.json.JacksonJsonDecoder;
import org.springframework.http.codec.json.JacksonJsonEncoder;
import org.springframework.http.codec.json.KotlinSerializationJsonDecoder;
import org.springframework.http.codec.json.KotlinSerializationJsonEncoder;
import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader;
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
@ -88,7 +92,7 @@ class CodecConfigurerTests { @@ -88,7 +92,7 @@ class CodecConfigurerTests {
@Test
void defaultReaders() {
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
assertThat(readers).hasSize(17);
assertThat(readers).hasSize(19);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
@ -100,18 +104,20 @@ class CodecConfigurerTests { @@ -100,18 +104,20 @@ class CodecConfigurerTests {
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(DefaultPartHttpMessageReader.class);
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageReader.class);
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartEventHttpMessageReader.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationJsonDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonJsonDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonSmileDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
assertStringDecoder(getNextDecoder(readers), false);
}
@Test
void defaultWriters() {
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
assertThat(writers).hasSize(16);
assertThat(writers).hasSize(18);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
@ -122,11 +128,13 @@ class CodecConfigurerTests { @@ -122,11 +128,13 @@ class CodecConfigurerTests {
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageWriter.class);
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(PartEventHttpMessageWriter.class);
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(PartHttpMessageWriter.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationJsonEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonJsonEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonSmileEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
assertStringEncoder(getNextEncoder(writers), false);
}
@ -152,7 +160,7 @@ class CodecConfigurerTests { @@ -152,7 +160,7 @@ class CodecConfigurerTests {
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
assertThat(readers).hasSize(21);
assertThat(readers).hasSize(23);
assertThat(getNextDecoder(readers)).isSameAs(customDecoder1);
assertThat(readers.get(this.index.getAndIncrement())).isSameAs(customReader1);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
@ -168,11 +176,13 @@ class CodecConfigurerTests { @@ -168,11 +176,13 @@ class CodecConfigurerTests {
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartEventHttpMessageReader.class);
assertThat(getNextDecoder(readers)).isSameAs(customDecoder2);
assertThat(readers.get(this.index.getAndIncrement())).isSameAs(customReader2);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationJsonDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonJsonDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonSmileDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(StringDecoder.class);
}
@ -198,7 +208,7 @@ class CodecConfigurerTests { @@ -198,7 +208,7 @@ class CodecConfigurerTests {
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
assertThat(writers).hasSize(20);
assertThat(writers).hasSize(22);
assertThat(getNextEncoder(writers)).isSameAs(customEncoder1);
assertThat(writers.get(this.index.getAndIncrement())).isSameAs(customWriter1);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
@ -213,11 +223,13 @@ class CodecConfigurerTests { @@ -213,11 +223,13 @@ class CodecConfigurerTests {
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(PartHttpMessageWriter.class);
assertThat(getNextEncoder(writers)).isSameAs(customEncoder2);
assertThat(writers.get(this.index.getAndIncrement())).isSameAs(customWriter2);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationJsonEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonJsonEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonSmileEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(CharSequenceEncoder.class);
}

26
spring-web/src/test/java/org/springframework/http/codec/support/ServerCodecConfigurerTests.java

@ -52,10 +52,14 @@ import org.springframework.http.codec.ResourceHttpMessageReader; @@ -52,10 +52,14 @@ import org.springframework.http.codec.ResourceHttpMessageReader;
import org.springframework.http.codec.ResourceHttpMessageWriter;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
import org.springframework.http.codec.cbor.JacksonCborDecoder;
import org.springframework.http.codec.cbor.JacksonCborEncoder;
import org.springframework.http.codec.cbor.KotlinSerializationCborDecoder;
import org.springframework.http.codec.cbor.KotlinSerializationCborEncoder;
import org.springframework.http.codec.json.JacksonJsonDecoder;
import org.springframework.http.codec.json.JacksonJsonEncoder;
import org.springframework.http.codec.json.KotlinSerializationJsonDecoder;
import org.springframework.http.codec.json.KotlinSerializationJsonEncoder;
import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader;
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
@ -91,7 +95,7 @@ class ServerCodecConfigurerTests { @@ -91,7 +95,7 @@ class ServerCodecConfigurerTests {
@Test
void defaultReaders() {
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
assertThat(readers).hasSize(17);
assertThat(readers).hasSize(19);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
@ -103,18 +107,20 @@ class ServerCodecConfigurerTests { @@ -103,18 +107,20 @@ class ServerCodecConfigurerTests {
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(DefaultPartHttpMessageReader.class);
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageReader.class);
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartEventHttpMessageReader.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationJsonDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonJsonDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonSmileDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(JacksonCborDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
assertStringDecoder(getNextDecoder(readers), false);
}
@Test
void defaultWriters() {
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
assertThat(writers).hasSize(17);
assertThat(writers).hasSize(19);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
@ -125,11 +131,13 @@ class ServerCodecConfigurerTests { @@ -125,11 +131,13 @@ class ServerCodecConfigurerTests {
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageWriter.class);
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartEventHttpMessageWriter.class);
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartHttpMessageWriter.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationJsonEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonJsonEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonSmileEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(JacksonCborEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
assertSseWriter(writers);
assertStringEncoder(getNextEncoder(writers), false);
}
@ -172,11 +180,13 @@ class ServerCodecConfigurerTests { @@ -172,11 +180,13 @@ class ServerCodecConfigurerTests {
assertThat((reader).getMaxInMemorySize()).isEqualTo(size);
assertThat(((PartEventHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationCborDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationProtobufDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationJsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((JacksonJsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((JacksonSmileDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationCborDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((JacksonCborDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((Jaxb2XmlDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((KotlinSerializationProtobufDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
assertThat(((StringDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
}

2
spring-webflux/src/test/java/org/springframework/web/reactive/config/DelegatingWebFluxConfigurationTests.java

@ -117,7 +117,7 @@ public class DelegatingWebFluxConfigurationTests { @@ -117,7 +117,7 @@ public class DelegatingWebFluxConfigurationTests {
boolean condition = initializer.getValidator() instanceof LocalValidatorFactoryBean;
assertThat(condition).isTrue();
assertThat(initializer.getConversionService()).isSameAs(formatterRegistry.getValue());
assertThat(codecsConfigurer.getValue().getReaders()).hasSize(15);
assertThat(codecsConfigurer.getValue().getReaders()).hasSize(16);
}
@Test

Loading…
Cancel
Save