mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-22 14:09:25 +00:00
Prevent Kotlin Serialization codecs side effects
This commit updates Kotlin serialization codecs to perform an additional check invoking KotlinDetector#hasSerializableAnnotation to decide if the related type should be processed or not. The goal is to prevent in the default arrangement conflicts between general purpose codecs like Jackson and Kotlin serialization when both are used. New constructors allowing to specify a custom predicate are also introduced. See gh-35761
This commit is contained in:
+22
-3
@@ -18,6 +18,7 @@ package org.springframework.http.codec;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.BinaryFormat;
|
||||
import kotlinx.serialization.KSerializer;
|
||||
@@ -37,9 +38,11 @@ import org.springframework.util.MimeType;
|
||||
* Abstract base class for {@link Decoder} implementations that defer to Kotlin
|
||||
* {@linkplain BinaryFormat binary serializers}.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only decodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics level
|
||||
* since it allows combined usage with other general purpose decoders without conflicts.
|
||||
* Alternative constructors with a {@code Predicate<ResolvableType>} parameter can be used
|
||||
* to customize this behavior.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Iain Henderson
|
||||
@@ -54,10 +57,26 @@ public abstract class KotlinSerializationBinaryDecoder<T extends BinaryFormat> e
|
||||
private final ByteArrayDecoder byteArrayDecoder = new ByteArrayDecoder();
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only decodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or
|
||||
* generics level.
|
||||
*/
|
||||
public KotlinSerializationBinaryDecoder(T format, MimeType... supportedMimeTypes) {
|
||||
super(format, supportedMimeTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only decodes types for which the specified predicate returns
|
||||
* {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationBinaryDecoder(T format, Predicate<ResolvableType> typePredicate, MimeType... supportedMimeTypes) {
|
||||
super(format, typePredicate, supportedMimeTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a limit on the number of bytes that can be buffered whenever
|
||||
* the input stream needs to be aggregated. This can be a result of
|
||||
|
||||
+22
-3
@@ -18,6 +18,7 @@ package org.springframework.http.codec;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.BinaryFormat;
|
||||
import kotlinx.serialization.KSerializer;
|
||||
@@ -38,9 +39,11 @@ import org.springframework.util.MimeType;
|
||||
* Abstract base class for {@link Encoder} implementations that defer to Kotlin
|
||||
* {@linkplain BinaryFormat binary serializers}.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only encodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics level
|
||||
* since it allows combined usage with other general purpose encoders without conflicts.
|
||||
* Alternative constructors with a {@code Predicate<ResolvableType>} parameter can be used
|
||||
* to customize this behavior.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Iain Henderson
|
||||
@@ -54,10 +57,26 @@ public abstract class KotlinSerializationBinaryEncoder<T extends BinaryFormat> e
|
||||
// ByteArraySequence encoding needed for now, see https://github.com/Kotlin/kotlinx.serialization/issues/204 for more details
|
||||
private final ByteArrayEncoder byteArrayEncoder = new ByteArrayEncoder();
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only encodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or
|
||||
* generics level.
|
||||
*/
|
||||
protected KotlinSerializationBinaryEncoder(T format, MimeType... supportedMimeTypes) {
|
||||
super(format, supportedMimeTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only encodes types for which the specified predicate returns
|
||||
* {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
protected KotlinSerializationBinaryEncoder(T format, Predicate<ResolvableType> typePredicate, MimeType... supportedMimeTypes) {
|
||||
super(format, typePredicate, supportedMimeTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
|
||||
return canSerialize(elementType, mimeType);
|
||||
|
||||
+22
-3
@@ -18,6 +18,7 @@ package org.springframework.http.codec;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.KSerializer;
|
||||
import kotlinx.serialization.StringFormat;
|
||||
@@ -38,9 +39,11 @@ import org.springframework.util.MimeType;
|
||||
* Abstract base class for {@link Decoder} implementations that defer to Kotlin
|
||||
* {@linkplain StringFormat string serializers}.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only decodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics level
|
||||
* since it allows combined usage with other general purpose decoders without conflicts.
|
||||
* Alternative constructors with a {@code Predicate<ResolvableType>} parameter can be used
|
||||
* to customize this behavior.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Iain Henderson
|
||||
@@ -55,10 +58,26 @@ public abstract class KotlinSerializationStringDecoder<T extends StringFormat> e
|
||||
private final StringDecoder stringDecoder = StringDecoder.allMimeTypes(StringDecoder.DEFAULT_DELIMITERS, false);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only decodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or
|
||||
* generics level.
|
||||
*/
|
||||
public KotlinSerializationStringDecoder(T format, MimeType... supportedMimeTypes) {
|
||||
super(format, supportedMimeTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only decodes types for which the specified predicate returns
|
||||
* {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationStringDecoder(T format, Predicate<ResolvableType> typePredicate, MimeType... supportedMimeTypes) {
|
||||
super(format, typePredicate, supportedMimeTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a limit on the number of bytes that can be buffered whenever
|
||||
* the input stream needs to be aggregated. This can be a result of
|
||||
|
||||
+23
-3
@@ -22,6 +22,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.KSerializer;
|
||||
import kotlinx.serialization.StringFormat;
|
||||
@@ -43,9 +44,11 @@ import org.springframework.util.MimeType;
|
||||
* Abstract base class for {@link Encoder} implementations that defer to Kotlin
|
||||
* {@linkplain StringFormat string serializers}.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only encodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics level
|
||||
* since it allows combined usage with other general purpose encoders without conflicts.
|
||||
* Alternative constructors with a {@code Predicate<ResolvableType>} parameter can be used
|
||||
* to customize this behavior.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Iain Henderson
|
||||
@@ -65,10 +68,27 @@ public abstract class KotlinSerializationStringEncoder<T extends StringFormat> e
|
||||
private final CharSequenceEncoder charSequenceEncoder = CharSequenceEncoder.allMimeTypes();
|
||||
private final Set<MimeType> streamingMediaTypes = new HashSet<>();
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only encodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or
|
||||
* generics level.
|
||||
*/
|
||||
protected KotlinSerializationStringEncoder(T format, MimeType... supportedMimeTypes) {
|
||||
super(format, supportedMimeTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only encodes types for which the specified predicate returns
|
||||
* {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
protected KotlinSerializationStringEncoder(T format, Predicate<ResolvableType> typePredicate, MimeType... supportedMimeTypes) {
|
||||
super(format, typePredicate, supportedMimeTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set streaming {@link MediaType MediaTypes}.
|
||||
* @param streamingMediaTypes streaming {@link MediaType MediaTypes}
|
||||
|
||||
+27
-12
@@ -21,6 +21,7 @@ import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlin.reflect.KFunction;
|
||||
import kotlin.reflect.KType;
|
||||
@@ -42,9 +43,11 @@ import org.springframework.util.MimeType;
|
||||
* Base class providing support methods for encoding and decoding with Kotlin
|
||||
* serialization.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only handles types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics level
|
||||
* since it allows combined usage with other general purpose decoders without conflicts.
|
||||
* Alternative constructors with a {@code Predicate<ResolvableType>} parameter can be used
|
||||
* to customize this behavior.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Iain Henderson
|
||||
@@ -63,12 +66,29 @@ public abstract class KotlinSerializationSupport<T extends SerialFormat> {
|
||||
|
||||
private final List<MimeType> supportedMimeTypes;
|
||||
|
||||
private final Predicate<ResolvableType> typePredicate;
|
||||
|
||||
/**
|
||||
* Creates a new instance of this support class with the given format
|
||||
* and supported mime types.
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only handle types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or
|
||||
* generics level.
|
||||
*/
|
||||
protected KotlinSerializationSupport(T format, MimeType... supportedMimeTypes) {
|
||||
this.format = format;
|
||||
this.typePredicate = KotlinDetector::hasSerializableAnnotation;
|
||||
this.supportedMimeTypes = Arrays.asList(supportedMimeTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only encode types for which the specified predicate returns
|
||||
* {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
protected KotlinSerializationSupport(T format, Predicate<ResolvableType> typePredicate, MimeType... supportedMimeTypes) {
|
||||
this.format = format;
|
||||
this.typePredicate = typePredicate;
|
||||
this.supportedMimeTypes = Arrays.asList(supportedMimeTypes);
|
||||
}
|
||||
|
||||
@@ -94,15 +114,10 @@ public abstract class KotlinSerializationSupport<T extends SerialFormat> {
|
||||
* @return {@code true} if {@code type} can be serialized; false otherwise
|
||||
*/
|
||||
protected final boolean canSerialize(ResolvableType type, @Nullable MimeType mimeType) {
|
||||
KSerializer<Object> serializer = serializer(type);
|
||||
if (serializer == null) {
|
||||
if (!this.typePredicate.test(type) || ResolvableType.NONE.equals(type)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return (supports(mimeType) && !String.class.isAssignableFrom(type.toClass()) &&
|
||||
!ServerSentEvent.class.isAssignableFrom(type.toClass()));
|
||||
}
|
||||
|
||||
return serializer(type) != null && supports(mimeType);
|
||||
}
|
||||
|
||||
private boolean supports(@Nullable MimeType mimeType) {
|
||||
|
||||
+44
-3
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.springframework.http.codec.cbor;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.cbor.Cbor;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.KotlinSerializationBinaryDecoder;
|
||||
|
||||
@@ -26,24 +29,62 @@ import org.springframework.http.codec.KotlinSerializationBinaryDecoder;
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization">kotlinx.serialization</a>.
|
||||
* It supports {@code application/cbor}.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only decodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics
|
||||
* level since it allows combined usage with other general purpose CBOR decoders
|
||||
* like {@link JacksonCborDecoder} without conflicts.
|
||||
*
|
||||
* <p>Alternative constructors with a {@code Predicate<ResolvableType>}
|
||||
* parameter can be used to customize this behavior. For example,
|
||||
* {@code new KotlinSerializationCborDecoder(type -> true)} will decode all types
|
||||
* supported by Kotlin Serialization, including unannotated Kotlin enumerations,
|
||||
* numbers, characters, booleans and strings.
|
||||
*
|
||||
* <p>Decoding streams is not supported yet, see
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/issues/1073">kotlinx.serialization/issues/1073</a>
|
||||
* related issue.
|
||||
*
|
||||
* @author Iain Henderson
|
||||
* @author Sebastien Deleuze
|
||||
* @since 6.0
|
||||
* @see KotlinSerializationCborEncoder
|
||||
*/
|
||||
public class KotlinSerializationCborDecoder extends KotlinSerializationBinaryDecoder<Cbor> {
|
||||
|
||||
/**
|
||||
* Construct a new decoder using {@link Cbor.Default} instance which
|
||||
* only decodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationCborDecoder() {
|
||||
this(Cbor.Default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new decoder using {@link Cbor.Default} instance which
|
||||
* only decodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationCborDecoder(Predicate<ResolvableType> typePredicate) {
|
||||
this(Cbor.Default, typePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new decoder using the provided {@link Cbor} instance which
|
||||
* only decodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationCborDecoder(Cbor cbor) {
|
||||
super(cbor, MediaType.APPLICATION_CBOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new decoder using the provided {@link Cbor} instance which
|
||||
* only decodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationCborDecoder(Cbor cbor, Predicate<ResolvableType> typePredicate) {
|
||||
super(cbor, typePredicate, MediaType.APPLICATION_CBOR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+43
-3
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.springframework.http.codec.cbor;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.cbor.Cbor;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.KotlinSerializationBinaryEncoder;
|
||||
|
||||
@@ -26,21 +29,58 @@ import org.springframework.http.codec.KotlinSerializationBinaryEncoder;
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization">kotlinx.serialization</a>.
|
||||
* It supports {@code application/cbor}.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only encodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics
|
||||
* level since it allows combined usage with other general purpose JSON encoders
|
||||
* like {@link JacksonCborEncoder} without conflicts.
|
||||
*
|
||||
* <p>Alternative constructors with a {@code Predicate<ResolvableType>}
|
||||
* parameter can be used to customize this behavior. For example,
|
||||
* {@code new KotlinSerializationCborEncoder(type -> true)} will encode all types
|
||||
* supported by Kotlin Serialization, including unannotated Kotlin enumerations,
|
||||
* numbers, characters, booleans and strings.
|
||||
*
|
||||
* @author Iain Henderson
|
||||
* @author Sebastien Deleuze
|
||||
* @since 6.0
|
||||
* @see KotlinSerializationCborDecoder
|
||||
*/
|
||||
public class KotlinSerializationCborEncoder extends KotlinSerializationBinaryEncoder<Cbor> {
|
||||
|
||||
/**
|
||||
* Construct a new encoder using {@link Cbor.Default} instance which
|
||||
* only encodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationCborEncoder() {
|
||||
this(Cbor.Default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new encoder using {@link Cbor.Default} instance which
|
||||
* only encodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationCborEncoder(Predicate<ResolvableType> typePredicate) {
|
||||
this(Cbor.Default, typePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new encoder using the provided {@link Cbor} instance which
|
||||
* only encodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationCborEncoder(Cbor cbor) {
|
||||
super(cbor, MediaType.APPLICATION_CBOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new encoder using the provided {@link Cbor} instance which
|
||||
* only encodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationCborEncoder(Cbor cbor, Predicate<ResolvableType> typePredicate) {
|
||||
super(cbor, typePredicate, MediaType.APPLICATION_CBOR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+50
-5
@@ -16,10 +16,14 @@
|
||||
|
||||
package org.springframework.http.codec.json;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.json.Json;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.KotlinSerializationStringDecoder;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
/**
|
||||
* Decode a byte stream into JSON and convert to Object's with
|
||||
@@ -27,9 +31,16 @@ import org.springframework.http.codec.KotlinSerializationStringDecoder;
|
||||
* It supports {@code application/json} and {@code application/*+json} with
|
||||
* various character sets, {@code UTF-8} being the default.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only decodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics
|
||||
* level since it allows combined usage with other general purpose JSON decoders
|
||||
* like {@link JacksonJsonDecoder} without conflicts.
|
||||
*
|
||||
* <p>Alternative constructors with a {@code Predicate<ResolvableType>}
|
||||
* parameter can be used to customize this behavior. For example,
|
||||
* {@code new KotlinSerializationJsonDecoder(type -> true)} will decode all types
|
||||
* supported by Kotlin Serialization, including unannotated Kotlin enumerations,
|
||||
* numbers, characters, booleans and strings.
|
||||
*
|
||||
* <p>Decoding streams is not supported yet, see
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/issues/1073">kotlinx.serialization/issues/1073</a>
|
||||
@@ -38,16 +49,50 @@ import org.springframework.http.codec.KotlinSerializationStringDecoder;
|
||||
* @author Sebastien Deleuze
|
||||
* @author Iain Henderson
|
||||
* @since 5.3
|
||||
* @see KotlinSerializationJsonEncoder
|
||||
*/
|
||||
public class KotlinSerializationJsonDecoder extends KotlinSerializationStringDecoder<Json> {
|
||||
|
||||
private static final MimeType[] DEFAULT_JSON_MIME_TYPES = new MimeType[] {
|
||||
MediaType.APPLICATION_JSON,
|
||||
new MediaType("application", "*+json"),
|
||||
MediaType.APPLICATION_NDJSON
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a new decoder using {@link Json.Default} instance which
|
||||
* only decodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationJsonDecoder() {
|
||||
this(Json.Default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new decoder using {@link Json.Default} instance which
|
||||
* only decodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationJsonDecoder(Predicate<ResolvableType> typePredicate) {
|
||||
this(Json.Default, typePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new decoder using the provided {@link Json} instance which
|
||||
* only decodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationJsonDecoder(Json json) {
|
||||
super(json, MediaType.APPLICATION_JSON, new MediaType("application", "*+json"),
|
||||
MediaType.APPLICATION_NDJSON);
|
||||
super(json, DEFAULT_JSON_MIME_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new decoder using the provided {@link Json} instance which
|
||||
* only decodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationJsonDecoder(Json json, Predicate<ResolvableType> typePredicate) {
|
||||
super(json, typePredicate, DEFAULT_JSON_MIME_TYPES);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+47
-5
@@ -18,6 +18,7 @@ package org.springframework.http.codec.json;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.json.Json;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@@ -38,23 +39,64 @@ import org.springframework.util.MimeType;
|
||||
* It supports {@code application/json}, {@code application/x-ndjson} and {@code application/*+json} with
|
||||
* various character sets, {@code UTF-8} being the default.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only encodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics
|
||||
* level.
|
||||
*
|
||||
* <p>Alternative constructors with a {@code Predicate<ResolvableType>}
|
||||
* parameter can be used to customize this behavior. For example,
|
||||
* {@code new KotlinSerializationJsonEncoder(type -> true)} will encode all types
|
||||
* supported by Kotlin Serialization, including unannotated Kotlin enumerations,
|
||||
* numbers, characters, booleans and strings.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Iain Henderson
|
||||
* @since 5.3
|
||||
* @see KotlinSerializationJsonDecoder
|
||||
*/
|
||||
public class KotlinSerializationJsonEncoder extends KotlinSerializationStringEncoder<Json> {
|
||||
|
||||
private static final MimeType[] DEFAULT_JSON_MIME_TYPES = new MimeType[] {
|
||||
MediaType.APPLICATION_JSON,
|
||||
new MediaType("application", "*+json"),
|
||||
MediaType.APPLICATION_NDJSON
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a new encoder using {@link Json.Default} instance which
|
||||
* only encodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationJsonEncoder() {
|
||||
this(Json.Default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new encoder using {@link Json.Default} instance which
|
||||
* only encodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationJsonEncoder(Predicate<ResolvableType> typePredicate) {
|
||||
this(Json.Default, typePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new encoder using the provided {@link Json} instance which
|
||||
* only encodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationJsonEncoder(Json json) {
|
||||
super(json, MediaType.APPLICATION_JSON, new MediaType("application", "*+json"),
|
||||
MediaType.APPLICATION_NDJSON);
|
||||
super(json, DEFAULT_JSON_MIME_TYPES);
|
||||
setStreamingMediaTypes(List.of(MediaType.APPLICATION_NDJSON));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new encoder using the provided {@link Json} instance which
|
||||
* only encodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationJsonEncoder(Json json, Predicate<ResolvableType> typePredicate) {
|
||||
super(json, typePredicate, DEFAULT_JSON_MIME_TYPES);
|
||||
setStreamingMediaTypes(List.of(MediaType.APPLICATION_NDJSON));
|
||||
}
|
||||
|
||||
|
||||
+43
-3
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.springframework.http.codec.protobuf;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.protobuf.ProtoBuf;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.codec.KotlinSerializationBinaryDecoder;
|
||||
|
||||
/**
|
||||
@@ -25,24 +28,61 @@ import org.springframework.http.codec.KotlinSerializationBinaryDecoder;
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization">kotlinx.serialization</a>.
|
||||
* It supports {@code application/x-protobuf}, {@code application/octet-stream}, and {@code application/vnd.google.protobuf}.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only decodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics
|
||||
* level.
|
||||
*
|
||||
* <p>Alternative constructors with a {@code Predicate<ResolvableType>}
|
||||
* parameter can be used to customize this behavior. For example,
|
||||
* {@code new KotlinSerializationProtobufDecoder(type -> true)} will decode all types
|
||||
* supported by Kotlin Serialization, including unannotated Kotlin enumerations,
|
||||
* numbers, characters, booleans and strings.
|
||||
*
|
||||
* <p>Decoding streams is not supported yet, see
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/issues/1073">kotlinx.serialization/issues/1073</a>
|
||||
* related issue.
|
||||
*
|
||||
* @author Iain Henderson
|
||||
* @author Sebastien Deleuze
|
||||
* @since 6.0
|
||||
* @see KotlinSerializationProtobufEncoder
|
||||
*/
|
||||
public class KotlinSerializationProtobufDecoder extends KotlinSerializationBinaryDecoder<ProtoBuf> {
|
||||
|
||||
/**
|
||||
* Construct a new decoder using {@link ProtoBuf.Default} instance which
|
||||
* only decodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
|
||||
public KotlinSerializationProtobufDecoder() {
|
||||
this(ProtoBuf.Default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new decoder using {@link ProtoBuf.Default} instance which
|
||||
* only decodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationProtobufDecoder(Predicate<ResolvableType> typePredicate) {
|
||||
this(ProtoBuf.Default, typePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new decoder using the provided {@link ProtoBuf} instance which
|
||||
* only decodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationProtobufDecoder(ProtoBuf protobuf) {
|
||||
super(protobuf, ProtobufCodecSupport.MIME_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new decoder using the provided {@link ProtoBuf} instance which
|
||||
* only decodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationProtobufDecoder(ProtoBuf protobuf, Predicate<ResolvableType> typePredicate) {
|
||||
super(protobuf, typePredicate, ProtobufCodecSupport.MIME_TYPES);
|
||||
}
|
||||
}
|
||||
|
||||
+42
-3
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.springframework.http.codec.protobuf;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.protobuf.ProtoBuf;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.codec.KotlinSerializationBinaryEncoder;
|
||||
|
||||
/**
|
||||
@@ -25,24 +28,60 @@ import org.springframework.http.codec.KotlinSerializationBinaryEncoder;
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization">kotlinx.serialization</a>.
|
||||
* It supports {@code application/x-protobuf}, {@code application/octet-stream}, and {@code application/vnd.google.protobuf}.
|
||||
*
|
||||
* <p>As of Spring Framework 7.0,
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism">open polymorphism</a>
|
||||
* is supported.
|
||||
* <p>As of Spring Framework 7.0, by default it only encodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics
|
||||
* level.
|
||||
*
|
||||
* <p>Alternative constructors with a {@code Predicate<ResolvableType>}
|
||||
* parameter can be used to customize this behavior. For example,
|
||||
* {@code new KotlinSerializationProtobufEncoder(type -> true)} will encode all types
|
||||
* supported by Kotlin Serialization, including unannotated Kotlin enumerations,
|
||||
* numbers, characters, booleans and strings.
|
||||
*
|
||||
* <p>Decoding streams is not supported yet, see
|
||||
* <a href="https://github.com/Kotlin/kotlinx.serialization/issues/1073">kotlinx.serialization/issues/1073</a>
|
||||
* related issue.
|
||||
*
|
||||
* @author Iain Henderson
|
||||
* @author Sebastien Deleuze
|
||||
* @since 6.0
|
||||
* @see KotlinSerializationProtobufDecoder
|
||||
*/
|
||||
public class KotlinSerializationProtobufEncoder extends KotlinSerializationBinaryEncoder<ProtoBuf> {
|
||||
|
||||
/**
|
||||
* Construct a new encoder using {@link ProtoBuf.Default} instance which
|
||||
* only encodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationProtobufEncoder() {
|
||||
this(ProtoBuf.Default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new encoder using {@link ProtoBuf.Default} instance which
|
||||
* only encodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationProtobufEncoder(Predicate<ResolvableType> typePredicate) {
|
||||
this(ProtoBuf.Default, typePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new encoder using the provided {@link ProtoBuf} instance which
|
||||
* only encodes types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationProtobufEncoder(ProtoBuf protobuf) {
|
||||
super(protobuf, ProtobufCodecSupport.MIME_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new encoder using the provided {@link ProtoBuf} instance which
|
||||
* only encodes types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationProtobufEncoder(ProtoBuf protobuf, Predicate<ResolvableType> typePredicate) {
|
||||
super(protobuf, typePredicate, ProtobufCodecSupport.MIME_TYPES);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user