diff --git a/spring-web/src/main/java/org/springframework/http/converter/DefaultHttpMessageConverters.java b/spring-web/src/main/java/org/springframework/http/converter/DefaultHttpMessageConverters.java index 66bd4e9b79f..1df9a640e14 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/DefaultHttpMessageConverters.java +++ b/spring-web/src/main/java/org/springframework/http/converter/DefaultHttpMessageConverters.java @@ -50,6 +50,7 @@ import org.springframework.util.ClassUtils; * Default implementation for {@link HttpMessageConverters}. * * @author Brian Clozel + * @author Sebastien Deleuze */ @SuppressWarnings("removal") class DefaultHttpMessageConverters implements HttpMessageConverters { @@ -122,6 +123,8 @@ class DefaultHttpMessageConverters implements HttpMessageConverters { @Nullable HttpMessageConverter smileConverter; + @Nullable HttpMessageConverter kotlinCborConverter; + @Nullable HttpMessageConverter cborConverter; @Nullable HttpMessageConverter yamlConverter; @@ -187,6 +190,11 @@ class DefaultHttpMessageConverters implements HttpMessageConverters { this.smileConverter = smileConverter; } + void setKotlinSerializationCborConverter(HttpMessageConverter kotlinCborConverter) { + Assert.notNull(kotlinCborConverter, "kotlinCborConverter must not be null"); + this.kotlinCborConverter = kotlinCborConverter; + } + void setCborConverter(HttpMessageConverter cborConverter) { Assert.isTrue(cborConverter.getSupportedMediaTypes().contains(MediaType.APPLICATION_CBOR), "cborConverter should support 'application/cbor'"); @@ -230,6 +238,9 @@ class DefaultHttpMessageConverters implements HttpMessageConverters { if (this.smileConverter != null) { converters.add(this.smileConverter); } + if (this.kotlinCborConverter != null) { + converters.add(this.kotlinCborConverter); + } if (this.cborConverter != null) { converters.add(this.cborConverter); } @@ -263,7 +274,12 @@ class DefaultHttpMessageConverters implements HttpMessageConverters { } if (this.kotlinJsonConverter == null) { if (KOTLIN_SERIALIZATION_JSON_PRESENT) { - this.kotlinJsonConverter = new KotlinSerializationJsonHttpMessageConverter(); + if (this.jsonConverter != null || JACKSON_PRESENT || JACKSON_2_PRESENT || GSON_PRESENT || JSONB_PRESENT) { + this.kotlinJsonConverter = new KotlinSerializationJsonHttpMessageConverter(); + } + else { + this.kotlinJsonConverter = new KotlinSerializationJsonHttpMessageConverter(type -> true); + } } } if (this.jsonConverter == null) { @@ -302,6 +318,16 @@ class DefaultHttpMessageConverters implements HttpMessageConverters { } } + if (this.kotlinCborConverter == null) { + if (KOTLIN_SERIALIZATION_CBOR_PRESENT) { + if (this.cborConverter != null || JACKSON_CBOR_PRESENT || JACKSON_2_CBOR_PRESENT) { + this.kotlinCborConverter = new KotlinSerializationCborHttpMessageConverter(); + } + else { + this.kotlinCborConverter = new KotlinSerializationCborHttpMessageConverter(type -> true); + } + } + } if (this.cborConverter == null) { if (JACKSON_CBOR_PRESENT) { this.cborConverter = new JacksonCborHttpMessageConverter(); @@ -309,9 +335,6 @@ class DefaultHttpMessageConverters implements HttpMessageConverters { else if (JACKSON_2_CBOR_PRESENT) { this.cborConverter = new MappingJackson2CborHttpMessageConverter(); } - else if (KOTLIN_SERIALIZATION_CBOR_PRESENT) { - this.cborConverter = new KotlinSerializationCborHttpMessageConverter(); - } } if (this.yamlConverter == null) { @@ -325,7 +348,7 @@ class DefaultHttpMessageConverters implements HttpMessageConverters { if (this.protobufConverter == null) { if (KOTLIN_SERIALIZATION_PROTOBUF_PRESENT) { - this.protobufConverter = new KotlinSerializationProtobufHttpMessageConverter(); + this.protobufConverter = new KotlinSerializationProtobufHttpMessageConverter(type -> true); } } @@ -379,6 +402,12 @@ class DefaultHttpMessageConverters implements HttpMessageConverters { return this; } + @Override + public ClientBuilder withKotlinSerializationCborConverter(HttpMessageConverter kotlinSerializationCborConverter) { + setKotlinSerializationCborConverter(kotlinSerializationCborConverter); + return this; + } + @Override public ClientBuilder withCborConverter(HttpMessageConverter cborConverter) { setCborConverter(cborConverter); @@ -470,6 +499,12 @@ class DefaultHttpMessageConverters implements HttpMessageConverters { return this; } + @Override + public ServerBuilder withKotlinSerializationCborConverter(HttpMessageConverter kotlinSerializationCborConverter) { + setKotlinSerializationCborConverter(kotlinSerializationCborConverter); + return this; + } + @Override public ServerBuilder withCborConverter(HttpMessageConverter cborConverter) { setCborConverter(cborConverter); diff --git a/spring-web/src/main/java/org/springframework/http/converter/HttpMessageConverters.java b/spring-web/src/main/java/org/springframework/http/converter/HttpMessageConverters.java index bd038304549..9c0293b31df 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/HttpMessageConverters.java +++ b/spring-web/src/main/java/org/springframework/http/converter/HttpMessageConverters.java @@ -27,6 +27,7 @@ import java.util.function.Consumer; * Finally, {@link Builder#configureMessageConverters(Consumer) default and custom converters can be configured}. * * @author Brian Clozel + * @author Sebastien Deleuze * @since 7.0 */ public interface HttpMessageConverters extends Iterable> { @@ -40,9 +41,10 @@ public interface HttpMessageConverters extends Iterable> *
  • {@link StringHttpMessageConverter} with the {@link java.nio.charset.StandardCharsets#ISO_8859_1} charset *
  • {@link ResourceHttpMessageConverter}, with resource streaming support disabled *
  • a Multipart converter, using all detected and custom converters for part conversion - *
  • A Kotlin Serialization converter + *
  • A Kotlin Serialization JSON converter *
  • A JSON converter *
  • A Smile converter + *
  • A Kotlin Serialization CBOR converter *
  • A CBOR converter *
  • A YAML converter *
  • An XML converter @@ -63,9 +65,10 @@ public interface HttpMessageConverters extends Iterable> *
  • {@link StringHttpMessageConverter} with the {@link java.nio.charset.StandardCharsets#ISO_8859_1} charset *
  • {@link ResourceHttpMessageConverter} *
  • {@link ResourceRegionHttpMessageConverter} - *
  • A Kotlin Serialization converter + *
  • A Kotlin Serialization JSON converter *
  • A JSON converter *
  • A Smile converter + *
  • A Kotlin Serialization CBOR converter *
  • A CBOR converter *
  • A YAML converter *
  • An XML converter @@ -128,6 +131,14 @@ public interface HttpMessageConverters extends Iterable> */ T withSmileConverter(HttpMessageConverter smileMessageConverter); + /** + * Override the default String {@code HttpMessageConverter} + * with any converter supporting the Kotlin Serialization conversion for CBOR. + * @param kotlinSerializationConverter the converter instance to use + * @see org.springframework.http.converter.cbor.KotlinSerializationCborHttpMessageConverter + */ + T withKotlinSerializationCborConverter(HttpMessageConverter kotlinSerializationConverter); + /** * Override the default Jackson 3.x CBOR {@code HttpMessageConverter} * with any converter supporting the CBOR format. diff --git a/spring-web/src/test/java/org/springframework/http/converter/DefaultHttpMessageConvertersTests.java b/spring-web/src/test/java/org/springframework/http/converter/DefaultHttpMessageConvertersTests.java index 1aef37b005a..8b56a3be5bb 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/DefaultHttpMessageConvertersTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/DefaultHttpMessageConvertersTests.java @@ -28,6 +28,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.converter.cbor.JacksonCborHttpMessageConverter; +import org.springframework.http.converter.cbor.KotlinSerializationCborHttpMessageConverter; import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter; import org.springframework.http.converter.feed.RssChannelHttpMessageConverter; import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; @@ -113,9 +114,10 @@ class DefaultHttpMessageConvertersTests { StringHttpMessageConverter.class, ResourceHttpMessageConverter.class, AllEncompassingFormHttpMessageConverter.class, KotlinSerializationJsonHttpMessageConverter.class, JacksonJsonHttpMessageConverter.class, JacksonSmileHttpMessageConverter.class, - JacksonCborHttpMessageConverter.class, JacksonYamlHttpMessageConverter.class, - JacksonXmlHttpMessageConverter.class, KotlinSerializationProtobufHttpMessageConverter.class, - AtomFeedHttpMessageConverter.class, RssChannelHttpMessageConverter.class); + KotlinSerializationCborHttpMessageConverter.class, JacksonCborHttpMessageConverter.class, + JacksonYamlHttpMessageConverter.class, JacksonXmlHttpMessageConverter.class, + KotlinSerializationProtobufHttpMessageConverter.class, AtomFeedHttpMessageConverter.class, + RssChannelHttpMessageConverter.class); } @Test @@ -127,9 +129,10 @@ class DefaultHttpMessageConvertersTests { ByteArrayHttpMessageConverter.class, StringHttpMessageConverter.class, ResourceHttpMessageConverter.class, KotlinSerializationJsonHttpMessageConverter.class, JacksonJsonHttpMessageConverter.class, JacksonSmileHttpMessageConverter.class, - JacksonCborHttpMessageConverter.class, JacksonYamlHttpMessageConverter.class, - JacksonXmlHttpMessageConverter.class, KotlinSerializationProtobufHttpMessageConverter.class, - AtomFeedHttpMessageConverter.class, RssChannelHttpMessageConverter.class); + KotlinSerializationCborHttpMessageConverter.class, JacksonCborHttpMessageConverter.class, + JacksonYamlHttpMessageConverter.class, JacksonXmlHttpMessageConverter.class, + KotlinSerializationProtobufHttpMessageConverter.class, AtomFeedHttpMessageConverter.class, + RssChannelHttpMessageConverter.class); } @Test @@ -148,9 +151,10 @@ class DefaultHttpMessageConvertersTests { StringHttpMessageConverter.class, ResourceHttpMessageConverter.class, AllEncompassingFormHttpMessageConverter.class, KotlinSerializationJsonHttpMessageConverter.class, JacksonJsonHttpMessageConverter.class, JacksonSmileHttpMessageConverter.class, - JacksonCborHttpMessageConverter.class, JacksonYamlHttpMessageConverter.class, - JacksonXmlHttpMessageConverter.class, KotlinSerializationProtobufHttpMessageConverter.class, - AtomFeedHttpMessageConverter.class, RssChannelHttpMessageConverter.class); + KotlinSerializationCborHttpMessageConverter.class, JacksonCborHttpMessageConverter.class, + JacksonYamlHttpMessageConverter.class, JacksonXmlHttpMessageConverter.class, + KotlinSerializationProtobufHttpMessageConverter.class, AtomFeedHttpMessageConverter.class, + RssChannelHttpMessageConverter.class); } @Test @@ -216,9 +220,10 @@ class DefaultHttpMessageConvertersTests { ResourceHttpMessageConverter.class, ResourceRegionHttpMessageConverter.class, AllEncompassingFormHttpMessageConverter.class, KotlinSerializationJsonHttpMessageConverter.class, JacksonJsonHttpMessageConverter.class, JacksonSmileHttpMessageConverter.class, - JacksonCborHttpMessageConverter.class, JacksonYamlHttpMessageConverter.class, - JacksonXmlHttpMessageConverter.class, KotlinSerializationProtobufHttpMessageConverter.class, - AtomFeedHttpMessageConverter.class, RssChannelHttpMessageConverter.class); + KotlinSerializationCborHttpMessageConverter.class, JacksonCborHttpMessageConverter.class, + JacksonYamlHttpMessageConverter.class, JacksonXmlHttpMessageConverter.class, + KotlinSerializationProtobufHttpMessageConverter.class, AtomFeedHttpMessageConverter.class, + RssChannelHttpMessageConverter.class); } @Test @@ -230,9 +235,10 @@ class DefaultHttpMessageConvertersTests { ByteArrayHttpMessageConverter.class, StringHttpMessageConverter.class, ResourceHttpMessageConverter.class, KotlinSerializationJsonHttpMessageConverter.class, JacksonJsonHttpMessageConverter.class, JacksonSmileHttpMessageConverter.class, - JacksonCborHttpMessageConverter.class, JacksonYamlHttpMessageConverter.class, - JacksonXmlHttpMessageConverter.class, KotlinSerializationProtobufHttpMessageConverter.class, - AtomFeedHttpMessageConverter.class, RssChannelHttpMessageConverter.class); + KotlinSerializationCborHttpMessageConverter.class, JacksonCborHttpMessageConverter.class, + JacksonYamlHttpMessageConverter.class, JacksonXmlHttpMessageConverter.class, + KotlinSerializationProtobufHttpMessageConverter.class, AtomFeedHttpMessageConverter.class, + RssChannelHttpMessageConverter.class); } @Test @@ -252,9 +258,10 @@ class DefaultHttpMessageConvertersTests { ResourceHttpMessageConverter.class, ResourceRegionHttpMessageConverter.class, AllEncompassingFormHttpMessageConverter.class, KotlinSerializationJsonHttpMessageConverter.class, JacksonJsonHttpMessageConverter.class, JacksonSmileHttpMessageConverter.class, - JacksonCborHttpMessageConverter.class, JacksonYamlHttpMessageConverter.class, - JacksonXmlHttpMessageConverter.class, KotlinSerializationProtobufHttpMessageConverter.class, - AtomFeedHttpMessageConverter.class, RssChannelHttpMessageConverter.class); + KotlinSerializationCborHttpMessageConverter.class, JacksonCborHttpMessageConverter.class, + JacksonYamlHttpMessageConverter.class, JacksonXmlHttpMessageConverter.class, + KotlinSerializationProtobufHttpMessageConverter.class, AtomFeedHttpMessageConverter.class, + RssChannelHttpMessageConverter.class); } @Test