Skip to content

Commit f6db2cc

Browse files
committed
Use serializerOrNull in Kotlin Serialization support
Closes gh-29068
1 parent ef7784f commit f6db2cc

File tree

4 files changed

+42
-65
lines changed

4 files changed

+42
-65
lines changed

spring-messaging/src/main/java/org/springframework/messaging/converter/KotlinSerializationJsonMessageConverter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -94,7 +94,6 @@ protected String toJson(Object payload, Type resolvedType) {
9494
* Tries to find a serializer that can marshall or unmarshall instances of the given type
9595
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
9696
* <p>Resolved serializers are cached and cached results are returned on successive calls.
97-
* TODO Avoid relying on throwing exception when https://github.com/Kotlin/kotlinx.serialization/pull/1164 is fixed
9897
* @param type the type to find a serializer for
9998
* @return a resolved serializer for the given type
10099
* @throws RuntimeException if no serializer supporting the given type can be found

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

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -100,13 +100,9 @@ public int getMaxInMemorySize() {
100100

101101
@Override
102102
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
103-
try {
104-
serializer(elementType.getType());
105-
return (super.canDecode(elementType, mimeType) && !CharSequence.class.isAssignableFrom(elementType.toClass()));
106-
}
107-
catch (Exception ex) {
108-
return false;
109-
}
103+
return (serializer(elementType.getType()) != null &&
104+
super.canDecode(elementType, mimeType) &&
105+
!CharSequence.class.isAssignableFrom(elementType.toClass()));
110106
}
111107

112108
@Override
@@ -129,17 +125,17 @@ public Mono<Object> decodeToMono(Publisher<DataBuffer> inputStream, ResolvableTy
129125
* Tries to find a serializer that can marshall or unmarshall instances of the given type
130126
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
131127
* <p>Resolved serializers are cached and cached results are returned on successive calls.
132-
* TODO Avoid relying on throwing exception when https://github.com/Kotlin/kotlinx.serialization/pull/1164 is fixed
133128
* @param type the type to find a serializer for
134-
* @return a resolved serializer for the given type
135-
* @throws RuntimeException if no serializer supporting the given type can be found
129+
* @return a resolved serializer for the given type or {@code null} if no serializer
130+
* supporting the given type can be found
136131
*/
132+
@Nullable
137133
private KSerializer<Object> serializer(Type type) {
138134
KSerializer<Object> serializer = serializerCache.get(type);
139135
if (serializer == null) {
140-
serializer = SerializersKt.serializer(type);
141-
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
142-
throw new UnsupportedOperationException("Open polymorphic serialization is not supported yet");
136+
serializer = SerializersKt.serializerOrNull(type);
137+
if (serializer == null || hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
138+
return null;
143139
}
144140
serializerCache.put(type, serializer);
145141
}

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

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -77,14 +77,10 @@ public KotlinSerializationJsonEncoder(Json json) {
7777

7878
@Override
7979
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
80-
try {
81-
serializer(elementType.getType());
82-
return (super.canEncode(elementType, mimeType) && !String.class.isAssignableFrom(elementType.toClass()) &&
83-
!ServerSentEvent.class.isAssignableFrom(elementType.toClass()));
84-
}
85-
catch (Exception ex) {
86-
return false;
87-
}
80+
return (serializer(elementType.getType()) != null &&
81+
super.canEncode(elementType, mimeType) &&
82+
!String.class.isAssignableFrom(elementType.toClass()) &&
83+
!ServerSentEvent.class.isAssignableFrom(elementType.toClass()));
8884
}
8985

9086
@Override
@@ -117,17 +113,17 @@ public DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory,
117113
* Tries to find a serializer that can marshall or unmarshall instances of the given type
118114
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
119115
* <p>Resolved serializers are cached and cached results are returned on successive calls.
120-
* TODO Avoid relying on throwing exception when https://github.com/Kotlin/kotlinx.serialization/pull/1164 is fixed
121116
* @param type the type to find a serializer for
122-
* @return a resolved serializer for the given type
123-
* @throws RuntimeException if no serializer supporting the given type can be found
117+
* @return a resolved serializer for the given type or {@code null} if no serializer
118+
* supporting the given type can be found
124119
*/
120+
@Nullable
125121
private KSerializer<Object> serializer(Type type) {
126122
KSerializer<Object> serializer = serializerCache.get(type);
127123
if (serializer == null) {
128-
serializer = SerializersKt.serializer(type);
129-
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
130-
throw new UnsupportedOperationException("Open polymorphic serialization is not supported yet");
124+
serializer = SerializersKt.serializerOrNull(type);
125+
if (serializer == null || hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
126+
return null;
131127
}
132128
serializerCache.put(type, serializer);
133129
}

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

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -39,6 +39,7 @@
3939
import org.springframework.http.converter.HttpMessageNotReadableException;
4040
import org.springframework.http.converter.HttpMessageNotWritableException;
4141
import org.springframework.lang.Nullable;
42+
import org.springframework.util.Assert;
4243
import org.springframework.util.ConcurrentReferenceHashMap;
4344
import org.springframework.util.StreamUtils;
4445

@@ -85,49 +86,33 @@ public KotlinSerializationJsonHttpMessageConverter(Json json) {
8586

8687
@Override
8788
protected boolean supports(Class<?> clazz) {
88-
try {
89-
serializer(clazz);
90-
return true;
91-
}
92-
catch (Exception ex) {
93-
return false;
94-
}
89+
return serializer(clazz) != null;
9590
}
9691

9792
@Override
9893
public boolean canRead(Type type, @Nullable Class<?> contextClass, @Nullable MediaType mediaType) {
99-
try {
100-
serializer(GenericTypeResolver.resolveType(type, contextClass));
101-
return canRead(mediaType);
102-
}
103-
catch (Exception ex) {
104-
return false;
105-
}
94+
return serializer(GenericTypeResolver.resolveType(type, contextClass)) != null && canRead(mediaType);
10695
}
10796

10897
@Override
10998
public boolean canWrite(@Nullable Type type, Class<?> clazz, @Nullable MediaType mediaType) {
110-
try {
111-
serializer(type != null ? GenericTypeResolver.resolveType(type, clazz) : clazz);
112-
return canWrite(mediaType);
113-
}
114-
catch (Exception ex) {
115-
return false;
116-
}
99+
return serializer(type != null ? GenericTypeResolver.resolveType(type, clazz) : clazz) != null && canWrite(mediaType);
117100
}
118101

119102
@Override
120103
public final Object read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage)
121104
throws IOException, HttpMessageNotReadableException {
122-
123-
return decode(serializer(GenericTypeResolver.resolveType(type, contextClass)), inputMessage);
105+
KSerializer<Object> serializer = serializer(GenericTypeResolver.resolveType(type, contextClass));
106+
Assert.notNull(serializer, "The serializer should not be null");
107+
return decode(serializer, inputMessage);
124108
}
125109

126110
@Override
127111
protected final Object readInternal(Class<?> clazz, HttpInputMessage inputMessage)
128112
throws IOException, HttpMessageNotReadableException {
129-
130-
return decode(serializer(clazz), inputMessage);
113+
KSerializer<Object> serializer = serializer(clazz);
114+
Assert.notNull(serializer, "The serializer should not be null");
115+
return decode(serializer, inputMessage);
131116
}
132117

133118
private Object decode(KSerializer<Object> serializer, HttpInputMessage inputMessage)
@@ -147,8 +132,9 @@ private Object decode(KSerializer<Object> serializer, HttpInputMessage inputMess
147132
@Override
148133
protected final void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage)
149134
throws IOException, HttpMessageNotWritableException {
150-
151-
encode(object, serializer(type != null ? type : object.getClass()), outputMessage);
135+
KSerializer<Object> serializer = serializer(type != null ? type : object.getClass());
136+
Assert.notNull(serializer, "The serializer should not be null");
137+
encode(object, serializer, outputMessage);
152138
}
153139

154140
private void encode(Object object, KSerializer<Object> serializer, HttpOutputMessage outputMessage)
@@ -179,17 +165,17 @@ private Charset getCharsetToUse(@Nullable MediaType contentType) {
179165
* Tries to find a serializer that can marshall or unmarshall instances of the given type
180166
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
181167
* <p>Resolved serializers are cached and cached results are returned on successive calls.
182-
* TODO Avoid relying on throwing exception when https://github.com/Kotlin/kotlinx.serialization/pull/1164 is fixed
183168
* @param type the type to find a serializer for
184-
* @return a resolved serializer for the given type
185-
* @throws RuntimeException if no serializer supporting the given type can be found
169+
* @return a resolved serializer for the given type or {@code null} if no serializer
170+
* supporting the given type can be found
186171
*/
172+
@Nullable
187173
private KSerializer<Object> serializer(Type type) {
188174
KSerializer<Object> serializer = serializerCache.get(type);
189175
if (serializer == null) {
190-
serializer = SerializersKt.serializer(type);
191-
if (hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
192-
throw new UnsupportedOperationException("Open polymorphic serialization is not supported yet");
176+
serializer = SerializersKt.serializerOrNull(type);
177+
if (serializer == null || hasPolymorphism(serializer.getDescriptor(), new HashSet<>())) {
178+
return null;
193179
}
194180
serializerCache.put(type, serializer);
195181
}

0 commit comments

Comments
 (0)