Browse Source

Support properties in kotlinx.serialization codecs

This commit adds support for Kotlin properties in Spring WebFlux
controllers, supported for reasons explained in gh-31856, with
kotlinx.serialization codecs.

See gh-34284
pull/34362/head
Sébastien Deleuze 11 months ago
parent
commit
a970fc16aa
  1. 31
      spring-web/src/main/java/org/springframework/http/codec/KotlinSerializationSupport.java
  2. 14
      spring-web/src/test/kotlin/org/springframework/http/codec/json/KotlinSerializationJsonEncoderTests.kt

31
spring-web/src/main/java/org/springframework/http/codec/KotlinSerializationSupport.java

@ -133,24 +133,25 @@ public abstract class KotlinSerializationSupport<T extends SerialFormat> { @@ -133,24 +133,25 @@ public abstract class KotlinSerializationSupport<T extends SerialFormat> {
Assert.notNull(method, "Method must not be null");
if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
Assert.notNull(function, "Kotlin function must not be null");
KType type = (parameter.getParameterIndex() == -1 ? function.getReturnType() :
KCallables.getValueParameters(function).get(parameter.getParameterIndex()).getType());
KSerializer<Object> serializer = this.kTypeSerializerCache.get(type);
if (serializer == null) {
try {
serializer = SerializersKt.serializerOrNull(this.format.getSerializersModule(), type);
}
catch (IllegalArgumentException ignored) {
}
if (serializer != null) {
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
return null;
if (function != null) {
KType type = (parameter.getParameterIndex() == -1 ? function.getReturnType() :
KCallables.getValueParameters(function).get(parameter.getParameterIndex()).getType());
KSerializer<Object> serializer = this.kTypeSerializerCache.get(type);
if (serializer == null) {
try {
serializer = SerializersKt.serializerOrNull(this.format.getSerializersModule(), type);
}
catch (IllegalArgumentException ignored) {
}
if (serializer != null) {
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
return null;
}
this.kTypeSerializerCache.put(type, serializer);
}
this.kTypeSerializerCache.put(type, serializer);
}
return serializer;
}
return serializer;
}
}
Type type = resolvableType.getType();

14
spring-web/src/test/kotlin/org/springframework/http/codec/json/KotlinSerializationJsonEncoderTests.kt

@ -145,10 +145,24 @@ class KotlinSerializationJsonEncoderTests : AbstractEncoderTests<KotlinSerializa @@ -145,10 +145,24 @@ class KotlinSerializationJsonEncoderTests : AbstractEncoderTests<KotlinSerializa
assertThat(encoder.canEncode(ResolvableType.forClass(BigDecimal::class.java), null)).isFalse()
}
@Test
fun encodeProperty() {
val input = Mono.just(value)
val method = this::class.java.getDeclaredMethod("getValue")
val methodParameter = MethodParameter.forExecutable(method, -1)
testEncode(input, ResolvableType.forMethodParameter(methodParameter), null, null) {
it.consumeNextWith(expectString("42"))
.verifyComplete()
}
}
@Serializable
data class Pojo(val foo: String, val bar: String, val pojo: Pojo? = null)
fun handleMapWithNullable(map: Map<String, String?>) = map
val value: Int
get() = 42
}

Loading…
Cancel
Save