mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Prevent Kotlin Serialization converters side effects
This commit updates Kotlin serialization converters 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 converters 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:
+35
-16
@@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlin.reflect.KType;
|
||||
import kotlinx.serialization.KSerializer;
|
||||
@@ -27,6 +28,7 @@ import kotlinx.serialization.SerialFormat;
|
||||
import kotlinx.serialization.SerializersKt;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.KotlinDetector;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
@@ -38,9 +40,11 @@ import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
* Abstract base class for {@link HttpMessageConverter} implementations that
|
||||
* use 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 encodes types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or generics level
|
||||
* since it allows combined usage with other general purpose converters without conflicts.
|
||||
* Alternative constructors with a {@code Predicate<ResolvableType>} parameter can be used
|
||||
* to customize this behavior.
|
||||
*
|
||||
* @author Andreas Ahlenstorf
|
||||
* @author Sebastien Deleuze
|
||||
@@ -58,15 +62,30 @@ public abstract class AbstractKotlinSerializationHttpMessageConverter<T extends
|
||||
|
||||
private final T format;
|
||||
|
||||
private final Predicate<ResolvableType> typePredicate;
|
||||
|
||||
|
||||
/**
|
||||
* Construct an {@code AbstractKotlinSerializationHttpMessageConverter} with multiple supported media type and
|
||||
* format.
|
||||
* @param format the format
|
||||
* @param supportedMediaTypes the supported media types
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only converters types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or
|
||||
* generics level.
|
||||
*/
|
||||
protected AbstractKotlinSerializationHttpMessageConverter(T format, MediaType... supportedMediaTypes) {
|
||||
super(supportedMediaTypes);
|
||||
this.typePredicate = KotlinDetector::hasSerializableAnnotation;
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only converts types for which the specified predicate returns
|
||||
* {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
protected AbstractKotlinSerializationHttpMessageConverter(T format, Predicate<ResolvableType> typePredicate, MediaType... supportedMediaTypes) {
|
||||
super(supportedMediaTypes);
|
||||
this.typePredicate = typePredicate;
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@@ -77,27 +96,27 @@ public abstract class AbstractKotlinSerializationHttpMessageConverter<T extends
|
||||
|
||||
@Override
|
||||
protected boolean supports(Class<?> clazz) {
|
||||
return serializer(ResolvableType.forClass(clazz), null) != null;
|
||||
ResolvableType type = ResolvableType.forClass(clazz);
|
||||
if (!this.typePredicate.test(type)) {
|
||||
return false;
|
||||
}
|
||||
return serializer(type, null) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(ResolvableType type, @Nullable MediaType mediaType) {
|
||||
if (!ResolvableType.NONE.equals(type) && serializer(type, null) != null) {
|
||||
return canRead(mediaType);
|
||||
}
|
||||
else {
|
||||
if (!this.typePredicate.test(type) || ResolvableType.NONE.equals(type)) {
|
||||
return false;
|
||||
}
|
||||
return serializer(type, null) != null && canRead(mediaType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(ResolvableType type, Class<?> clazz, @Nullable MediaType mediaType) {
|
||||
if (!ResolvableType.NONE.equals(type) && serializer(type, null) != null) {
|
||||
return canWrite(mediaType);
|
||||
}
|
||||
else {
|
||||
if (!this.typePredicate.test(type) || ResolvableType.NONE.equals(type)) {
|
||||
return false;
|
||||
}
|
||||
return serializer(type, null) != null && canWrite(mediaType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+21
-4
@@ -17,11 +17,13 @@
|
||||
package org.springframework.http.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.BinaryFormat;
|
||||
import kotlinx.serialization.KSerializer;
|
||||
import kotlinx.serialization.SerializationException;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -31,9 +33,11 @@ import org.springframework.util.StreamUtils;
|
||||
* Abstract base class for {@link HttpMessageConverter} 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 converters without conflicts.
|
||||
* Alternative constructors with a {@code Predicate<ResolvableType>} parameter can be used
|
||||
* to customize this behavior.
|
||||
*
|
||||
* @author Andreas Ahlenstorf
|
||||
* @author Sebastien Deleuze
|
||||
@@ -47,12 +51,25 @@ public abstract class KotlinSerializationBinaryHttpMessageConverter<T extends Bi
|
||||
extends AbstractKotlinSerializationHttpMessageConverter<T> {
|
||||
|
||||
/**
|
||||
* Construct an {@code KotlinSerializationBinaryHttpMessageConverter} with format and supported media types.
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only converters types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or
|
||||
* generics level.
|
||||
*/
|
||||
protected KotlinSerializationBinaryHttpMessageConverter(T format, MediaType... supportedMediaTypes) {
|
||||
super(format, supportedMediaTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only converts types for which the specified predicate returns
|
||||
* {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
protected KotlinSerializationBinaryHttpMessageConverter(T format, Predicate<ResolvableType> typePredicate, MediaType... supportedMediaTypes) {
|
||||
super(format, typePredicate, supportedMediaTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object readInternal(KSerializer<Object> serializer, T format, HttpInputMessage inputMessage)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
|
||||
+21
-4
@@ -19,12 +19,14 @@ package org.springframework.http.converter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.KSerializer;
|
||||
import kotlinx.serialization.SerializationException;
|
||||
import kotlinx.serialization.StringFormat;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -34,9 +36,11 @@ import org.springframework.util.StreamUtils;
|
||||
* Abstract base class for {@link HttpMessageConverter} 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 converters without conflicts.
|
||||
* Alternative constructors with a {@code Predicate<ResolvableType>} parameter can be used
|
||||
* to customize this behavior.
|
||||
*
|
||||
* @author Andreas Ahlenstorf
|
||||
* @author Sebastien Deleuze
|
||||
@@ -51,12 +55,25 @@ public abstract class KotlinSerializationStringHttpMessageConverter<T extends St
|
||||
|
||||
|
||||
/**
|
||||
* Construct an {@code KotlinSerializationStringHttpMessageConverter} with format and supported media types.
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only converters types annotated with
|
||||
* {@link kotlinx.serialization.Serializable @Serializable} at type or
|
||||
* generics level.
|
||||
*/
|
||||
protected KotlinSerializationStringHttpMessageConverter(T format, MediaType... supportedMediaTypes) {
|
||||
super(format, supportedMediaTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given format and supported mime types
|
||||
* which only converts types for which the specified predicate returns
|
||||
* {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
protected KotlinSerializationStringHttpMessageConverter(T format, Predicate<ResolvableType> typePredicate, MediaType... supportedMediaTypes) {
|
||||
super(format, typePredicate, supportedMediaTypes);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object readInternal(KSerializer<Object> serializer, T format, HttpInputMessage inputMessage)
|
||||
|
||||
+42
-3
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.springframework.http.converter.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.converter.KotlinSerializationBinaryHttpMessageConverter;
|
||||
|
||||
@@ -27,20 +30,56 @@ import org.springframework.http.converter.KotlinSerializationBinaryHttpMessageCo
|
||||
* <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 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 JacksonCborHttpMessageConverter} without conflicts.
|
||||
*
|
||||
* <p>Alternative constructors with a {@code Predicate<ResolvableType>}
|
||||
* parameter can be used to customize this behavior. For example,
|
||||
* {@code new KotlinSerializationCborHttpMessageConverter(type -> true)} will decode all types
|
||||
* supported by Kotlin Serialization, including unannotated Kotlin enumerations,
|
||||
* numbers, characters, booleans and strings.
|
||||
*
|
||||
* @author Iain Henderson
|
||||
* @author Sebastien Deleuze
|
||||
* @since 6.0
|
||||
*/
|
||||
public class KotlinSerializationCborHttpMessageConverter extends KotlinSerializationBinaryHttpMessageConverter<Cbor> {
|
||||
|
||||
/**
|
||||
* Construct a new converter using {@link Cbor.Default} instance which
|
||||
* only converts types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationCborHttpMessageConverter() {
|
||||
this(Cbor.Default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new converter using {@link Cbor.Default} instance which
|
||||
* only converts types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationCborHttpMessageConverter(Predicate<ResolvableType> typePredicate) {
|
||||
this(Cbor.Default, typePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new converter using the provided {@link Cbor} instance which
|
||||
* only converts types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationCborHttpMessageConverter(Cbor cbor) {
|
||||
super(cbor, MediaType.APPLICATION_CBOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new converter using the provided {@link Cbor} instance which
|
||||
* only converts types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationCborHttpMessageConverter(Cbor cbor, Predicate<ResolvableType> typePredicate) {
|
||||
super(cbor, typePredicate, MediaType.APPLICATION_CBOR);
|
||||
}
|
||||
}
|
||||
|
||||
+41
-6
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.springframework.http.converter.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.converter.KotlinSerializationStringHttpMessageConverter;
|
||||
|
||||
@@ -28,9 +31,16 @@ import org.springframework.http.converter.KotlinSerializationStringHttpMessageCo
|
||||
* 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 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 JacksonJsonHttpMessageConverter} without conflicts.
|
||||
*
|
||||
* <p>Alternative constructors with a {@code Predicate<ResolvableType>}
|
||||
* parameter can be used to customize this behavior. For example,
|
||||
* {@code new KotlinSerializationJsonHttpMessageConverter(type -> true)} will decode all types
|
||||
* supported by Kotlin Serialization, including unannotated Kotlin enumerations,
|
||||
* numbers, characters, booleans and strings.
|
||||
*
|
||||
* @author Andreas Ahlenstorf
|
||||
* @author Sebastien Deleuze
|
||||
@@ -40,17 +50,42 @@ import org.springframework.http.converter.KotlinSerializationStringHttpMessageCo
|
||||
*/
|
||||
public class KotlinSerializationJsonHttpMessageConverter extends KotlinSerializationStringHttpMessageConverter<Json> {
|
||||
|
||||
private static final MediaType[] DEFAULT_JSON_MIME_TYPES = new MediaType[] {
|
||||
MediaType.APPLICATION_JSON, new MediaType("application", "*+json") };
|
||||
|
||||
/**
|
||||
* Construct a new {@code KotlinSerializationJsonHttpMessageConverter} with the default configuration.
|
||||
* Construct a new converter using {@link Json.Default} instance which
|
||||
* only converts types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationJsonHttpMessageConverter() {
|
||||
this(Json.Default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code KotlinSerializationJsonHttpMessageConverter} with a custom configuration.
|
||||
* Construct a new converter using {@link Json.Default} instance which
|
||||
* only converts types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationJsonHttpMessageConverter(Predicate<ResolvableType> typePredicate) {
|
||||
this(Json.Default, typePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new converter using the provided {@link Json} instance which
|
||||
* only converts types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationJsonHttpMessageConverter(Json json) {
|
||||
super(json, MediaType.APPLICATION_JSON, new MediaType("application", "*+json"));
|
||||
super(json, DEFAULT_JSON_MIME_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new converter using the provided {@link Json} instance which
|
||||
* only converts types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationJsonHttpMessageConverter(Json json, Predicate<ResolvableType> typePredicate) {
|
||||
super(json, typePredicate, DEFAULT_JSON_MIME_TYPES);
|
||||
}
|
||||
}
|
||||
|
||||
+42
-3
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.springframework.http.converter.protobuf;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import kotlinx.serialization.protobuf.ProtoBuf;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.KotlinSerializationBinaryHttpMessageConverter;
|
||||
|
||||
@@ -27,23 +30,59 @@ import org.springframework.http.converter.KotlinSerializationBinaryHttpMessageCo
|
||||
* <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 converts 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 KotlinSerializationProtobufHttpMessageConverter(type -> true)} will convert all types
|
||||
* supported by Kotlin Serialization, including unannotated Kotlin enumerations,
|
||||
* numbers, characters, booleans and strings.
|
||||
*
|
||||
* @author Iain Henderson
|
||||
* @author Sebstien Deleuze
|
||||
* @since 6.0
|
||||
*/
|
||||
public class KotlinSerializationProtobufHttpMessageConverter extends
|
||||
KotlinSerializationBinaryHttpMessageConverter<ProtoBuf> {
|
||||
|
||||
/**
|
||||
* Construct a new converter using {@link ProtoBuf.Default} instance which
|
||||
* only converts types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationProtobufHttpMessageConverter() {
|
||||
this(ProtoBuf.Default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new converter using {@link ProtoBuf.Default} instance which
|
||||
* only converts types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationProtobufHttpMessageConverter(Predicate<ResolvableType> typePredicate) {
|
||||
this(ProtoBuf.Default, typePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new converter using the provided {@link ProtoBuf} instance which
|
||||
* only converts types annotated with {@link kotlinx.serialization.Serializable @Serializable}
|
||||
* at type or generics level.
|
||||
*/
|
||||
public KotlinSerializationProtobufHttpMessageConverter(ProtoBuf protobuf) {
|
||||
super(protobuf, MediaType.APPLICATION_PROTOBUF, MediaType.APPLICATION_OCTET_STREAM,
|
||||
new MediaType("application", "vnd.google.protobuf"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new converter using the provided {@link ProtoBuf} instance which
|
||||
* only converts types for which the specified predicate returns {@code true}.
|
||||
* @since 7.0
|
||||
*/
|
||||
public KotlinSerializationProtobufHttpMessageConverter(ProtoBuf protobuf, Predicate<ResolvableType> typePredicate) {
|
||||
super(protobuf, typePredicate, MediaType.APPLICATION_PROTOBUF, MediaType.APPLICATION_OCTET_STREAM,
|
||||
new MediaType("application", "vnd.google.protobuf"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+68
-17
@@ -33,6 +33,7 @@ import org.springframework.core.Ordered
|
||||
import org.springframework.core.ResolvableType
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException
|
||||
import org.springframework.http.converter.json.KotlinSerializationJsonHttpMessageConverter
|
||||
import org.springframework.web.testfixture.http.MockHttpInputMessage
|
||||
import org.springframework.web.testfixture.http.MockHttpOutputMessage
|
||||
|
||||
@@ -56,57 +57,107 @@ class KotlinSerializationCborHttpMessageConverterTests {
|
||||
fraction = 42f
|
||||
)
|
||||
private val serializableBeanArray = arrayOf(serializableBean)
|
||||
private val serializableBeanArrayBody = Cbor.Default.encodeToByteArray(serializableBeanArray)
|
||||
private val serializableBeanArrayBody = Cbor.encodeToByteArray(serializableBeanArray)
|
||||
|
||||
@Test
|
||||
fun canReadCbor() {
|
||||
assertThat(converter.canRead(SerializableBean::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(String::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(String::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canRead(NotSerializableBean::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
|
||||
assertThat(converter.canRead(Map::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(Map::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<Map<String, SerializableBean>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(List::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<SerializableBean>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(Set::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(Set::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<Set<SerializableBean>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<ArrayList<Int>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<ArrayList<Int>>(), MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converter.canRead(resolvableTypeOf<Ordered>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Ordered>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<Ordered>(), MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Ordered>>(), MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<OrderedImpl>(), MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<OrderedImpl>>(), MediaType.APPLICATION_CBOR)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canReadCborWithAllTypes() {
|
||||
val converterWithAllTypes = KotlinSerializationCborHttpMessageConverter { true }
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(SerializableBean::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converterWithAllTypes.canRead(String::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(NotSerializableBean::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(Map::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<Map<String, SerializableBean>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<SerializableBean>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(Set::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<Set<SerializableBean>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<ArrayList<Int>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<Ordered>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<Ordered>>(), MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<OrderedImpl>(), MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<OrderedImpl>>(), MediaType.APPLICATION_CBOR)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canWriteCbor() {
|
||||
assertThat(converter.canWrite(SerializableBean::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canWrite(String::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(String::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canWrite(NotSerializableBean::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
|
||||
assertThat(converter.canWrite(Map::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(Map::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Map<String, SerializableBean>>(), Map::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(List::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<SerializableBean>>(), List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(Set::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(Set::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Set<SerializableBean>>(), Set::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<ArrayList<Int>>(), List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<ArrayList<Int>>(), List::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Ordered>(), Ordered::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Ordered>(), Ordered::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<OrderedImpl>(), Ordered::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canWriteCborWithAllTypes() {
|
||||
val converterWithAllTypes = KotlinSerializationCborHttpMessageConverter { true }
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(SerializableBean::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converterWithAllTypes.canWrite(String::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(NotSerializableBean::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(Map::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Map<String, SerializableBean>>(), Map::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<List<SerializableBean>>(), List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(Set::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Set<SerializableBean>>(), Set::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<ArrayList<Int>>(), List::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Ordered>(), Ordered::class.java, MediaType.APPLICATION_CBOR)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<OrderedImpl>(), Ordered::class.java, MediaType.APPLICATION_CBOR)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun readObject() {
|
||||
val serializableBeanBody = Cbor.Default.encodeToByteArray(serializableBean)
|
||||
val serializableBeanBody = Cbor.encodeToByteArray(serializableBean)
|
||||
val inputMessage = MockHttpInputMessage(serializableBeanBody)
|
||||
inputMessage.headers.contentType = MediaType.APPLICATION_CBOR
|
||||
val result = converter.read(SerializableBean::class.java, inputMessage) as SerializableBean
|
||||
|
||||
+75
-18
@@ -45,7 +45,6 @@ import kotlin.reflect.typeOf
|
||||
* @author Andreas Ahlenstorf
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@Suppress("UsePropertyAccessSyntax")
|
||||
class KotlinSerializationJsonHttpMessageConverterTests {
|
||||
|
||||
private val converter = KotlinSerializationJsonHttpMessageConverter()
|
||||
@@ -54,22 +53,22 @@ class KotlinSerializationJsonHttpMessageConverterTests {
|
||||
fun canReadJson() {
|
||||
assertThat(converter.canRead(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(SerializableBean::class.java, MediaType.APPLICATION_PDF)).isFalse()
|
||||
assertThat(converter.canRead(String::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(String::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(NotSerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converter.canRead(Map::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(Map::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<Map<String, SerializableBean>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(List::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<SerializableBean>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(Set::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<Set<SerializableBean>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<ArrayList<Int>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<ArrayList<Int>>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_PDF)).isFalse()
|
||||
|
||||
assertThat(converter.canRead(resolvableTypeOf<Ordered>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Ordered>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<Ordered>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Ordered>>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<OrderedImpl>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<OrderedImpl>>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
@@ -78,25 +77,55 @@ class KotlinSerializationJsonHttpMessageConverterTests {
|
||||
assertThat(converter.canRead(ResolvableType.forType(BigDecimal::class.java), MediaType.APPLICATION_JSON)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canReadJsonWithAllTypes() {
|
||||
val converterWithAllTypes = KotlinSerializationJsonHttpMessageConverter { true }
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(SerializableBean::class.java, MediaType.APPLICATION_PDF)).isFalse()
|
||||
assertThat(converterWithAllTypes.canRead(String::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(NotSerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(Map::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<Map<String, SerializableBean>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<SerializableBean>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<Set<SerializableBean>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<ArrayList<Int>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_PDF)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<Ordered>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<Ordered>>(), MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<OrderedImpl>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<OrderedImpl>>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(ResolvableType.forType(ResolvableType.NONE.type), MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(ResolvableType.forType(BigDecimal::class.java), MediaType.APPLICATION_JSON)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canWriteJson() {
|
||||
assertThat(converter.canWrite(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(SerializableBean::class.java, MediaType.APPLICATION_PDF)).isFalse()
|
||||
assertThat(converter.canWrite(String::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(String::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canWrite(NotSerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converter.canWrite(Map::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(Map::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Map<String, SerializableBean>>(), Map::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(List::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<SerializableBean>>(), List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(Set::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Set<SerializableBean>>(), Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<ArrayList<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<ArrayList<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_PDF)).isFalse()
|
||||
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Ordered>(), Ordered::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Ordered>(), Ordered::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<OrderedImpl>(), OrderedImpl::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converter.canWrite(ResolvableType.NONE, SerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
@@ -104,6 +133,34 @@ class KotlinSerializationJsonHttpMessageConverterTests {
|
||||
assertThat(converter.canWrite(ResolvableType.forType(BigDecimal::class.java), BigDecimal::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canWriteJsonWithAllTypes() {
|
||||
val converterWithAllTypes = KotlinSerializationJsonHttpMessageConverter { true }
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(SerializableBean::class.java, MediaType.APPLICATION_PDF)).isFalse()
|
||||
assertThat(converterWithAllTypes.canWrite(String::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(NotSerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(Map::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Map<String, SerializableBean>>(), Map::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<List<SerializableBean>>(), List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Set<SerializableBean>>(), Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<ArrayList<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_PDF)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Ordered>(), Ordered::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<OrderedImpl>(), OrderedImpl::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(ResolvableType.NONE, SerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(ResolvableType.forType(BigDecimal::class.java), BigDecimal::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canReadMicroformats() {
|
||||
val jsonSubtype = MediaType("application", "vnd.test-micro-type+json")
|
||||
@@ -364,13 +421,13 @@ class KotlinSerializationJsonHttpMessageConverterTests {
|
||||
|
||||
@Test
|
||||
fun canReadBigDecimalWithSerializerModule() {
|
||||
val customConverter = KotlinSerializationJsonHttpMessageConverter(customJson)
|
||||
val customConverter = KotlinSerializationJsonHttpMessageConverter(customJson) { true }
|
||||
assertThat(customConverter.canRead(BigDecimal::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canWriteBigDecimalWithSerializerModule() {
|
||||
val customConverter = KotlinSerializationJsonHttpMessageConverter(customJson)
|
||||
val customConverter = KotlinSerializationJsonHttpMessageConverter(customJson) { true }
|
||||
assertThat(customConverter.canWrite(BigDecimal::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||
}
|
||||
|
||||
|
||||
+74
-17
@@ -27,6 +27,7 @@ import org.springframework.core.Ordered
|
||||
import org.springframework.core.ResolvableType
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException
|
||||
import org.springframework.http.converter.cbor.KotlinSerializationCborHttpMessageConverter
|
||||
import org.springframework.web.testfixture.http.MockHttpInputMessage
|
||||
import org.springframework.web.testfixture.http.MockHttpOutputMessage
|
||||
import java.lang.reflect.ParameterizedType
|
||||
@@ -59,26 +60,27 @@ class KotlinSerializationProtobufHttpMessageConverterTests {
|
||||
fraction = 42f
|
||||
)
|
||||
private val serializableBeanArray = arrayOf(serializableBean)
|
||||
private val serializableBeanArrayBody = ProtoBuf.Default.encodeToByteArray(serializableBeanArray)
|
||||
private val serializableBeanArrayBody = ProtoBuf.encodeToByteArray(serializableBeanArray)
|
||||
|
||||
@Test
|
||||
fun canReadProtobuf() {
|
||||
for (mimeType in mediaTypes) {
|
||||
assertThat(converter.canRead(SerializableBean::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canRead(String::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canRead(String::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canRead(NotSerializableBean::class.java, mimeType)).isFalse()
|
||||
|
||||
assertThat(converter.canRead(Map::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canRead(Map::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<Map<String, SerializableBean>>(), mimeType)).isTrue()
|
||||
assertThat(converter.canRead(List::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canRead(List::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<SerializableBean>>(), mimeType)).isTrue()
|
||||
assertThat(converter.canRead(Set::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canRead(Set::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<Set<SerializableBean>>(), mimeType)).isTrue()
|
||||
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Int>>(), mimeType)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<ArrayList<Int>>(),mimeType)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Int>>(), mimeType)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<ArrayList<Int>>(),mimeType)).isFalse()
|
||||
|
||||
assertThat(converter.canRead(resolvableTypeOf<Ordered>(), mimeType)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Ordered>>(), mimeType)).isTrue()
|
||||
assertThat(converter.canRead(resolvableTypeOf<Ordered>(), mimeType)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Ordered>>(), mimeType)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<OrderedImpl>(), mimeType)).isFalse()
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<OrderedImpl>>(), mimeType)).isFalse()
|
||||
}
|
||||
@@ -86,31 +88,86 @@ class KotlinSerializationProtobufHttpMessageConverterTests {
|
||||
assertThat(converter.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canReadProtobufForAllTypes() {
|
||||
val converterWithAllTypes = KotlinSerializationProtobufHttpMessageConverter { true }
|
||||
|
||||
for (mimeType in mediaTypes) {
|
||||
assertThat(converterWithAllTypes.canRead(SerializableBean::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(String::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(NotSerializableBean::class.java, mimeType)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(Map::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<Map<String, SerializableBean>>(), mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(List::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<SerializableBean>>(), mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(Set::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<Set<SerializableBean>>(), mimeType)).isTrue()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<Int>>(), mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<ArrayList<Int>>(),mimeType)).isTrue()
|
||||
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<Ordered>(), mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<Ordered>>(), mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<OrderedImpl>(), mimeType)).isFalse()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<OrderedImpl>>(), mimeType)).isFalse()
|
||||
}
|
||||
assertThat(converterWithAllTypes.canRead(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converterWithAllTypes.canRead(resolvableTypeOf<List<Int>>(), MediaType.APPLICATION_JSON)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canWriteProtobuf() {
|
||||
for (mimeType in mediaTypes) {
|
||||
assertThat(converter.canWrite(SerializableBean::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(String::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(String::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canWrite(NotSerializableBean::class.java, mimeType)).isFalse()
|
||||
|
||||
assertThat(converter.canWrite(Map::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(Map::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Map<String, SerializableBean>>(), Map::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(List::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(List::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<SerializableBean>>(), List::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(Set::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(Set::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Set<SerializableBean>>(), Set::class.java, mimeType)).isTrue()
|
||||
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<ArrayList<Int>>(), List::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<ArrayList<Int>>(), List::class.java, mimeType)).isFalse()
|
||||
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Ordered>(), Ordered::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Ordered>(), OrderedImpl::class.java, mimeType)).isTrue()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Ordered>(), Ordered::class.java, mimeType)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<Ordered>(), OrderedImpl::class.java, mimeType)).isFalse()
|
||||
}
|
||||
|
||||
assertThat(converter.canWrite(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converter.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun canWriteProtobufForAllTypes() {
|
||||
val converterWithAllTypes = KotlinSerializationProtobufHttpMessageConverter { true }
|
||||
|
||||
for (mimeType in mediaTypes) {
|
||||
assertThat(converterWithAllTypes.canWrite(SerializableBean::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(String::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(NotSerializableBean::class.java, mimeType)).isFalse()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(Map::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Map<String, SerializableBean>>(), Map::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(List::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<List<SerializableBean>>(), List::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(Set::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Set<SerializableBean>>(), Set::class.java, mimeType)).isTrue()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<ArrayList<Int>>(), List::class.java, mimeType)).isTrue()
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Ordered>(), Ordered::class.java, mimeType)).isTrue()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<Ordered>(), OrderedImpl::class.java, mimeType)).isTrue()
|
||||
}
|
||||
|
||||
assertThat(converterWithAllTypes.canWrite(SerializableBean::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
assertThat(converterWithAllTypes.canWrite(resolvableTypeOf<List<Int>>(), List::class.java, MediaType.APPLICATION_JSON)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun readObject() {
|
||||
val serializableBeanBody = ProtoBuf.Default.encodeToByteArray(serializableBean)
|
||||
|
||||
+2
-2
@@ -109,7 +109,7 @@ class RequestResponseBodyMethodProcessorKotlinTests {
|
||||
val handlerMethod = HandlerMethod(SampleController(), method)
|
||||
val methodReturnType = handlerMethod.returnType
|
||||
|
||||
val converters = listOf(KotlinSerializationJsonHttpMessageConverter())
|
||||
val converters = listOf(KotlinSerializationJsonHttpMessageConverter { true })
|
||||
val processor = RequestResponseBodyMethodProcessor(converters, null, listOf(KotlinResponseBodyAdvice()))
|
||||
|
||||
val returnValue: Any = SampleController().writeNullableMap()
|
||||
@@ -179,7 +179,7 @@ class RequestResponseBodyMethodProcessorKotlinTests {
|
||||
this.servletRequest.setContent(content.toByteArray(StandardCharsets.UTF_8))
|
||||
this.servletRequest.setContentType("application/json")
|
||||
|
||||
val converters = listOf(StringHttpMessageConverter(), KotlinSerializationJsonHttpMessageConverter())
|
||||
val converters = listOf(StringHttpMessageConverter(), KotlinSerializationJsonHttpMessageConverter { true })
|
||||
val processor = RequestResponseBodyMethodProcessor(converters, null, listOf(KotlinRequestBodyAdvice()))
|
||||
|
||||
val method = SampleController::readNullableMap::javaMethod.get()!!
|
||||
|
||||
Reference in New Issue
Block a user