Skip to content

Commit 1167b30

Browse files
committed
Merge branch '6.2.x'
2 parents 86b04b7 + 5499878 commit 1167b30

File tree

4 files changed

+68
-38
lines changed

4 files changed

+68
-38
lines changed

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

+16-15
Original file line numberDiff line numberDiff line change
@@ -132,24 +132,25 @@ private boolean supports(@Nullable MimeType mimeType) {
132132
Assert.notNull(method, "Method must not be null");
133133
if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {
134134
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
135-
Assert.notNull(function, "Kotlin function must not be null");
136-
KType type = (parameter.getParameterIndex() == -1 ? function.getReturnType() :
137-
KCallables.getValueParameters(function).get(parameter.getParameterIndex()).getType());
138-
KSerializer<Object> serializer = this.kTypeSerializerCache.get(type);
139-
if (serializer == null) {
140-
try {
141-
serializer = SerializersKt.serializerOrNull(this.format.getSerializersModule(), type);
142-
}
143-
catch (IllegalArgumentException ignored) {
144-
}
145-
if (serializer != null) {
146-
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
147-
return null;
135+
if (function != null) {
136+
KType type = (parameter.getParameterIndex() == -1 ? function.getReturnType() :
137+
KCallables.getValueParameters(function).get(parameter.getParameterIndex()).getType());
138+
KSerializer<Object> serializer = this.kTypeSerializerCache.get(type);
139+
if (serializer == null) {
140+
try {
141+
serializer = SerializersKt.serializerOrNull(this.format.getSerializersModule(), type);
142+
}
143+
catch (IllegalArgumentException ignored) {
144+
}
145+
if (serializer != null) {
146+
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
147+
return null;
148+
}
149+
this.kTypeSerializerCache.put(type, serializer);
148150
}
149-
this.kTypeSerializerCache.put(type, serializer);
150151
}
152+
return serializer;
151153
}
152-
return serializer;
153154
}
154155
}
155156
Type type = resolvableType.getType();

spring-web/src/main/java/org/springframework/http/converter/AbstractKotlinSerializationHttpMessageConverter.java

+16-15
Original file line numberDiff line numberDiff line change
@@ -149,24 +149,25 @@ protected abstract void writeInternal(Object object, KSerializer<Object> seriali
149149
Assert.notNull(method, "Method must not be null");
150150
if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {
151151
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
152-
Assert.notNull(function, "Kotlin function must not be null");
153-
KType type = (parameter.getParameterIndex() == -1 ? function.getReturnType() :
154-
KCallables.getValueParameters(function).get(parameter.getParameterIndex()).getType());
155-
KSerializer<Object> serializer = this.kTypeSerializerCache.get(type);
156-
if (serializer == null) {
157-
try {
158-
serializer = SerializersKt.serializerOrNull(this.format.getSerializersModule(), type);
159-
}
160-
catch (IllegalArgumentException ignored) {
161-
}
162-
if (serializer != null) {
163-
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
164-
return null;
152+
if (function != null) {
153+
KType type = (parameter.getParameterIndex() == -1 ? function.getReturnType() :
154+
KCallables.getValueParameters(function).get(parameter.getParameterIndex()).getType());
155+
KSerializer<Object> serializer = this.kTypeSerializerCache.get(type);
156+
if (serializer == null) {
157+
try {
158+
serializer = SerializersKt.serializerOrNull(this.format.getSerializersModule(), type);
159+
}
160+
catch (IllegalArgumentException ignored) {
161+
}
162+
if (serializer != null) {
163+
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
164+
return null;
165+
}
166+
this.kTypeSerializerCache.put(type, serializer);
165167
}
166-
this.kTypeSerializerCache.put(type, serializer);
167168
}
169+
return serializer;
168170
}
169-
return serializer;
170171
}
171172
}
172173
Type type = resolvableType.getType();

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

+14
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,24 @@ class KotlinSerializationJsonEncoderTests : AbstractEncoderTests<KotlinSerializa
145145
assertThat(encoder.canEncode(ResolvableType.forClass(BigDecimal::class.java), null)).isFalse()
146146
}
147147

148+
@Test
149+
fun encodeProperty() {
150+
val input = Mono.just(value)
151+
val method = this::class.java.getDeclaredMethod("getValue")
152+
val methodParameter = MethodParameter.forExecutable(method, -1)
153+
testEncode(input, ResolvableType.forMethodParameter(methodParameter), null, null) {
154+
it.consumeNextWith(expectString("42"))
155+
.verifyComplete()
156+
}
157+
}
158+
148159

149160
@Serializable
150161
data class Pojo(val foo: String, val bar: String, val pojo: Pojo? = null)
151162

152163
fun handleMapWithNullable(map: Map<String, String?>) = map
153164

165+
val value: Int
166+
get() = 42
167+
154168
}

spring-web/src/test/kotlin/org/springframework/http/converter/json/KotlinSerializationJsonHttpMessageConverterTests.kt

+22-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,27 +16,24 @@
1616

1717
package org.springframework.http.converter.json
1818

19-
import java.lang.reflect.ParameterizedType
20-
import java.lang.reflect.Type
21-
import java.nio.charset.StandardCharsets
22-
2319
import kotlinx.serialization.Serializable
2420
import org.assertj.core.api.Assertions.assertThat
2521
import org.assertj.core.api.Assertions.assertThatExceptionOfType
2622
import org.junit.jupiter.api.Test
2723
import org.springframework.core.MethodParameter
28-
import kotlin.reflect.javaType
29-
import kotlin.reflect.typeOf
30-
3124
import org.springframework.core.Ordered
3225
import org.springframework.core.ResolvableType
3326
import org.springframework.http.MediaType
3427
import org.springframework.http.converter.HttpMessageNotReadableException
3528
import org.springframework.http.customJson
3629
import org.springframework.web.testfixture.http.MockHttpInputMessage
3730
import org.springframework.web.testfixture.http.MockHttpOutputMessage
31+
import java.lang.reflect.ParameterizedType
3832
import java.math.BigDecimal
33+
import java.nio.charset.StandardCharsets
34+
import kotlin.reflect.javaType
3935
import kotlin.reflect.jvm.javaMethod
36+
import kotlin.reflect.typeOf
4037

4138
/**
4239
* Tests for the JSON conversion using kotlinx.serialization.
@@ -395,6 +392,20 @@ class KotlinSerializationJsonHttpMessageConverterTests {
395392
assertThat(result).isEqualTo(expectedJson)
396393
}
397394

395+
@Test
396+
fun writeProperty() {
397+
val outputMessage = MockHttpOutputMessage()
398+
val method = this::class.java.getDeclaredMethod("getValue")
399+
val methodParameter = MethodParameter.forExecutable(method, -1)
400+
401+
this.converter.write(value, ResolvableType.forMethodParameter(methodParameter), null, outputMessage, null)
402+
val result = outputMessage.getBodyAsString(StandardCharsets.UTF_8)
403+
404+
@Suppress("DEPRECATION")
405+
assertThat(outputMessage.headers.asMultiValueMap()).containsEntry("Content-Type", listOf("application/json"))
406+
assertThat(result).isEqualTo("42")
407+
}
408+
398409

399410
@Serializable
400411
@Suppress("ArrayInDataClass")
@@ -420,4 +431,7 @@ class KotlinSerializationJsonHttpMessageConverterTests {
420431

421432
fun handleMapWithNullable(map: Map<String, String?>) = map
422433

434+
val value: Int
435+
get() = 42
436+
423437
}

0 commit comments

Comments
 (0)