Configure Kotlin JSON converters as Jackson alternative
Prior to this commit, Spring MVC and WebFlux would consider the "kotlinx.serialization" JSON codecs and converters in addition to other JSON alternatives like Jackson, Gson and Jsonb. This would cause issues because while in most cases this library is only involved if the type is annotated with "@Serializable", this is not true for Java enums. In this particular case, the codec shadows Jackson and causes issues. This commit now considers kotlinx.serialization JSON support as an alternative to Jackson. Just like Jsonb and GSON, this is only auto-detected if Jackson is not present. We received consistent feedback that kotlinx.serialization is popular in Kotlin libraries and is often a transitive dependency. As a result, we cannot consider its presence on the classpath as a strong enough signal to configure it by default. Closes gh-34410
This commit is contained in:
@@ -575,9 +575,6 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||
(KotlinSerializationCborDecoder) this.kotlinSerializationCborDecoder :
|
||||
new KotlinSerializationCborDecoder()));
|
||||
}
|
||||
if (kotlinSerializationJsonPresent) {
|
||||
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getKotlinSerializationJsonDecoder()));
|
||||
}
|
||||
if (kotlinSerializationProtobufPresent) {
|
||||
addCodec(this.objectReaders,
|
||||
new DecoderHttpMessageReader<>(this.kotlinSerializationProtobufDecoder != null ?
|
||||
@@ -587,6 +584,9 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||
if (jackson2Present) {
|
||||
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getJackson2JsonDecoder()));
|
||||
}
|
||||
else if (kotlinSerializationJsonPresent) {
|
||||
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getKotlinSerializationJsonDecoder()));
|
||||
}
|
||||
if (jackson2SmilePresent) {
|
||||
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(this.jackson2SmileDecoder != null ?
|
||||
(Jackson2SmileDecoder) this.jackson2SmileDecoder : new Jackson2SmileDecoder()));
|
||||
@@ -713,9 +713,6 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||
(KotlinSerializationCborEncoder) this.kotlinSerializationCborEncoder :
|
||||
new KotlinSerializationCborEncoder()));
|
||||
}
|
||||
if (kotlinSerializationJsonPresent) {
|
||||
addCodec(writers, new EncoderHttpMessageWriter<>(getKotlinSerializationJsonEncoder()));
|
||||
}
|
||||
if (kotlinSerializationProtobufPresent) {
|
||||
addCodec(writers, new EncoderHttpMessageWriter<>(this.kotlinSerializationProtobufEncoder != null ?
|
||||
(KotlinSerializationProtobufEncoder) this.kotlinSerializationProtobufEncoder :
|
||||
@@ -724,6 +721,9 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||
if (jackson2Present) {
|
||||
addCodec(writers, new EncoderHttpMessageWriter<>(getJackson2JsonEncoder()));
|
||||
}
|
||||
else if (kotlinSerializationJsonPresent) {
|
||||
addCodec(writers, new EncoderHttpMessageWriter<>(getKotlinSerializationJsonEncoder()));
|
||||
}
|
||||
if (jackson2SmilePresent) {
|
||||
addCodec(writers, new EncoderHttpMessageWriter<>(this.jackson2SmileEncoder != null ?
|
||||
(Jackson2SmileEncoder) this.jackson2SmileEncoder : new Jackson2SmileEncoder()));
|
||||
|
||||
@@ -60,8 +60,6 @@ import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
||||
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;
|
||||
@@ -94,7 +92,7 @@ class ClientCodecConfigurerTests {
|
||||
@Test
|
||||
void defaultReaders() {
|
||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||
assertThat(readers).hasSize(19);
|
||||
assertThat(readers).hasSize(18);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
|
||||
@@ -108,7 +106,6 @@ class ClientCodecConfigurerTests {
|
||||
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(KotlinSerializationJsonDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
||||
@@ -120,7 +117,7 @@ class ClientCodecConfigurerTests {
|
||||
@Test
|
||||
void defaultWriters() {
|
||||
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
||||
assertThat(writers).hasSize(17);
|
||||
assertThat(writers).hasSize(16);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
|
||||
@@ -132,7 +129,6 @@ class ClientCodecConfigurerTests {
|
||||
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(KotlinSerializationJsonEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
||||
@@ -188,7 +184,7 @@ class ClientCodecConfigurerTests {
|
||||
int size = 99;
|
||||
this.configurer.defaultCodecs().maxInMemorySize(size);
|
||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||
assertThat(readers).hasSize(19);
|
||||
assertThat(readers).hasSize(18);
|
||||
assertThat(((ByteArrayDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((ByteBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((DataBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
@@ -201,7 +197,6 @@ class ClientCodecConfigurerTests {
|
||||
nextReader(readers);
|
||||
assertThat(((PartEventHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((KotlinSerializationCborDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((KotlinSerializationJsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((KotlinSerializationProtobufDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((Jackson2JsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((Jackson2SmileDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
@@ -250,7 +245,7 @@ class ClientCodecConfigurerTests {
|
||||
writers = findCodec(this.configurer.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
||||
|
||||
assertThat(sseDecoder).isNotSameAs(jackson2Decoder);
|
||||
assertThat(writers).hasSize(17);
|
||||
assertThat(writers).hasSize(16);
|
||||
}
|
||||
|
||||
@Test // gh-24194
|
||||
@@ -260,7 +255,7 @@ class ClientCodecConfigurerTests {
|
||||
List<HttpMessageWriter<?>> writers =
|
||||
findCodec(clone.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
||||
|
||||
assertThat(writers).hasSize(17);
|
||||
assertThat(writers).hasSize(16);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -274,7 +269,7 @@ class ClientCodecConfigurerTests {
|
||||
List<HttpMessageWriter<?>> writers =
|
||||
findCodec(clone.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
||||
|
||||
assertThat(writers).hasSize(17);
|
||||
assertThat(writers).hasSize(16);
|
||||
}
|
||||
|
||||
private Decoder<?> getNextDecoder(List<HttpMessageReader<?>> readers) {
|
||||
|
||||
@@ -53,8 +53,6 @@ import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
||||
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;
|
||||
@@ -90,7 +88,7 @@ class CodecConfigurerTests {
|
||||
@Test
|
||||
void defaultReaders() {
|
||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||
assertThat(readers).hasSize(18);
|
||||
assertThat(readers).hasSize(17);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
|
||||
@@ -103,7 +101,6 @@ class CodecConfigurerTests {
|
||||
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(KotlinSerializationJsonDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
||||
@@ -114,7 +111,7 @@ class CodecConfigurerTests {
|
||||
@Test
|
||||
void defaultWriters() {
|
||||
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
||||
assertThat(writers).hasSize(17);
|
||||
assertThat(writers).hasSize(16);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
|
||||
@@ -126,7 +123,6 @@ class CodecConfigurerTests {
|
||||
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(KotlinSerializationJsonEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
||||
@@ -156,7 +152,7 @@ class CodecConfigurerTests {
|
||||
|
||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||
|
||||
assertThat(readers).hasSize(22);
|
||||
assertThat(readers).hasSize(21);
|
||||
assertThat(getNextDecoder(readers)).isSameAs(customDecoder1);
|
||||
assertThat(readers.get(this.index.getAndIncrement())).isSameAs(customReader1);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
||||
@@ -173,7 +169,6 @@ class CodecConfigurerTests {
|
||||
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(KotlinSerializationJsonDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
||||
@@ -203,7 +198,7 @@ class CodecConfigurerTests {
|
||||
|
||||
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
||||
|
||||
assertThat(writers).hasSize(21);
|
||||
assertThat(writers).hasSize(20);
|
||||
assertThat(getNextEncoder(writers)).isSameAs(customEncoder1);
|
||||
assertThat(writers.get(this.index.getAndIncrement())).isSameAs(customWriter1);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
||||
@@ -219,7 +214,6 @@ class CodecConfigurerTests {
|
||||
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(KotlinSerializationJsonEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
||||
|
||||
@@ -58,8 +58,6 @@ import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
||||
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;
|
||||
@@ -92,7 +90,7 @@ class ServerCodecConfigurerTests {
|
||||
@Test
|
||||
void defaultReaders() {
|
||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||
assertThat(readers).hasSize(18);
|
||||
assertThat(readers).hasSize(17);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
|
||||
@@ -105,7 +103,6 @@ class ServerCodecConfigurerTests {
|
||||
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(KotlinSerializationJsonDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationProtobufDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
||||
@@ -116,7 +113,7 @@ class ServerCodecConfigurerTests {
|
||||
@Test
|
||||
void defaultWriters() {
|
||||
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
||||
assertThat(writers).hasSize(18);
|
||||
assertThat(writers).hasSize(17);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
|
||||
@@ -128,7 +125,6 @@ class ServerCodecConfigurerTests {
|
||||
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(KotlinSerializationJsonEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationProtobufEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
||||
@@ -176,7 +172,6 @@ class ServerCodecConfigurerTests {
|
||||
assertThat(((PartEventHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
|
||||
assertThat(((KotlinSerializationCborDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((KotlinSerializationJsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((KotlinSerializationProtobufDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((Jackson2JsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
assertThat(((Jackson2SmileDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||
|
||||
Reference in New Issue
Block a user