Refine kotlinx.serialization support
This commit introduces the following changes: - Converters/codecs are now used based on generic type info. - On WebMvc and WebFlux, kotlinx.serialization is enabled along to Jackson because it only serializes Kotlin @Serializable classes which is not enough for error or actuator endpoints in Boot as described on spring-projects/spring-boot#24238. TODO: leverage Kotlin/kotlinx.serialization#1164 when fixed. Closes gh-26147
This commit is contained in:
parent
1f701d9bad
commit
43faa439ab
|
|
@ -94,6 +94,7 @@ public class KotlinSerializationJsonMessageConverter extends AbstractJsonMessage
|
||||||
* Tries to find a serializer that can marshall or unmarshall instances of the given type
|
* Tries to find a serializer that can marshall or unmarshall instances of the given type
|
||||||
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
|
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
|
||||||
* <p>Resolved serializers are cached and cached results are returned on successive calls.
|
* <p>Resolved serializers are cached and cached results are returned on successive calls.
|
||||||
|
* TODO Avoid relying on throwing exception when https://github.com/Kotlin/kotlinx.serialization/pull/1164 is fixed
|
||||||
* @param type the type to find a serializer for
|
* @param type the type to find a serializer for
|
||||||
* @return a resolved serializer for the given type
|
* @return a resolved serializer for the given type
|
||||||
* @throws RuntimeException if no serializer supporting the given type can be found
|
* @throws RuntimeException if no serializer supporting the given type can be found
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,38 @@ public class KotlinSerializationJsonDecoder extends AbstractDecoder<Object> {
|
||||||
this.json = json;
|
this.json = json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* decoding to a single {@code DataBuffer},
|
||||||
|
* {@link java.nio.ByteBuffer ByteBuffer}, {@code byte[]},
|
||||||
|
* {@link org.springframework.core.io.Resource Resource}, {@code String}, etc.
|
||||||
|
* It can also occur when splitting the input stream, e.g. delimited text,
|
||||||
|
* in which case the limit applies to data buffered between delimiters.
|
||||||
|
* <p>By default this is set to 256K.
|
||||||
|
* @param byteCount the max number of bytes to buffer, or -1 for unlimited
|
||||||
|
*/
|
||||||
|
public void setMaxInMemorySize(int byteCount) {
|
||||||
|
this.stringDecoder.setMaxInMemorySize(byteCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link #setMaxInMemorySize configured} byte count limit.
|
||||||
|
*/
|
||||||
|
public int getMaxInMemorySize() {
|
||||||
|
return this.stringDecoder.getMaxInMemorySize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
|
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
|
||||||
return (super.canDecode(elementType, mimeType) && !CharSequence.class.isAssignableFrom(elementType.toClass()));
|
try {
|
||||||
|
serializer(elementType.getType());
|
||||||
|
return (super.canDecode(elementType, mimeType) && !CharSequence.class.isAssignableFrom(elementType.toClass()));
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -95,6 +123,7 @@ public class KotlinSerializationJsonDecoder extends AbstractDecoder<Object> {
|
||||||
* Tries to find a serializer that can marshall or unmarshall instances of the given type
|
* Tries to find a serializer that can marshall or unmarshall instances of the given type
|
||||||
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
|
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
|
||||||
* <p>Resolved serializers are cached and cached results are returned on successive calls.
|
* <p>Resolved serializers are cached and cached results are returned on successive calls.
|
||||||
|
* TODO Avoid relying on throwing exception when https://github.com/Kotlin/kotlinx.serialization/pull/1164 is fixed
|
||||||
* @param type the type to find a serializer for
|
* @param type the type to find a serializer for
|
||||||
* @return a resolved serializer for the given type
|
* @return a resolved serializer for the given type
|
||||||
* @throws RuntimeException if no serializer supporting the given type can be found
|
* @throws RuntimeException if no serializer supporting the given type can be found
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,14 @@ public class KotlinSerializationJsonEncoder extends AbstractEncoder<Object> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
|
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
|
||||||
return (super.canEncode(elementType, mimeType) && !String.class.isAssignableFrom(elementType.toClass()) &&
|
try {
|
||||||
!ServerSentEvent.class.isAssignableFrom(elementType.toClass()));
|
serializer(elementType.getType());
|
||||||
|
return (super.canEncode(elementType, mimeType) && !String.class.isAssignableFrom(elementType.toClass()) &&
|
||||||
|
!ServerSentEvent.class.isAssignableFrom(elementType.toClass()));
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -105,6 +111,7 @@ public class KotlinSerializationJsonEncoder extends AbstractEncoder<Object> {
|
||||||
* Tries to find a serializer that can marshall or unmarshall instances of the given type
|
* Tries to find a serializer that can marshall or unmarshall instances of the given type
|
||||||
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
|
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
|
||||||
* <p>Resolved serializers are cached and cached results are returned on successive calls.
|
* <p>Resolved serializers are cached and cached results are returned on successive calls.
|
||||||
|
* TODO Avoid relying on throwing exception when https://github.com/Kotlin/kotlinx.serialization/pull/1164 is fixed
|
||||||
* @param type the type to find a serializer for
|
* @param type the type to find a serializer for
|
||||||
* @return a resolved serializer for the given type
|
* @return a resolved serializer for the given type
|
||||||
* @throws RuntimeException if no serializer supporting the given type can be found
|
* @throws RuntimeException if no serializer supporting the given type can be found
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,11 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
((ProtobufDecoder) codec).setMaxMessageSize(size);
|
((ProtobufDecoder) codec).setMaxMessageSize(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (kotlinSerializationJsonPresent) {
|
||||||
|
if (codec instanceof KotlinSerializationJsonDecoder) {
|
||||||
|
((KotlinSerializationJsonDecoder) codec).setMaxInMemorySize(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (jackson2Present) {
|
if (jackson2Present) {
|
||||||
if (codec instanceof AbstractJackson2Decoder) {
|
if (codec instanceof AbstractJackson2Decoder) {
|
||||||
((AbstractJackson2Decoder) codec).setMaxInMemorySize(size);
|
((AbstractJackson2Decoder) codec).setMaxInMemorySize(size);
|
||||||
|
|
@ -385,12 +390,12 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
||||||
|
if (kotlinSerializationJsonPresent) {
|
||||||
|
addCodec(readers, new DecoderHttpMessageReader<>(getKotlinSerializationJsonDecoder()));
|
||||||
|
}
|
||||||
if (jackson2Present) {
|
if (jackson2Present) {
|
||||||
addCodec(readers, new DecoderHttpMessageReader<>(getJackson2JsonDecoder()));
|
addCodec(readers, new DecoderHttpMessageReader<>(getJackson2JsonDecoder()));
|
||||||
}
|
}
|
||||||
else if (kotlinSerializationJsonPresent) {
|
|
||||||
addCodec(readers, new DecoderHttpMessageReader<>(getKotlinSerializationJsonDecoder()));
|
|
||||||
}
|
|
||||||
if (jackson2SmilePresent) {
|
if (jackson2SmilePresent) {
|
||||||
addCodec(readers, new DecoderHttpMessageReader<>(this.jackson2SmileDecoder != null ?
|
addCodec(readers, new DecoderHttpMessageReader<>(this.jackson2SmileDecoder != null ?
|
||||||
(Jackson2SmileDecoder) this.jackson2SmileDecoder : new Jackson2SmileDecoder()));
|
(Jackson2SmileDecoder) this.jackson2SmileDecoder : new Jackson2SmileDecoder()));
|
||||||
|
|
@ -484,12 +489,12 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
|
||||||
*/
|
*/
|
||||||
final List<HttpMessageWriter<?>> getBaseObjectWriters() {
|
final List<HttpMessageWriter<?>> getBaseObjectWriters() {
|
||||||
List<HttpMessageWriter<?>> writers = new ArrayList<>();
|
List<HttpMessageWriter<?>> writers = new ArrayList<>();
|
||||||
|
if (kotlinSerializationJsonPresent) {
|
||||||
|
writers.add(new EncoderHttpMessageWriter<>(getKotlinSerializationJsonEncoder()));
|
||||||
|
}
|
||||||
if (jackson2Present) {
|
if (jackson2Present) {
|
||||||
writers.add(new EncoderHttpMessageWriter<>(getJackson2JsonEncoder()));
|
writers.add(new EncoderHttpMessageWriter<>(getJackson2JsonEncoder()));
|
||||||
}
|
}
|
||||||
else if (kotlinSerializationJsonPresent) {
|
|
||||||
writers.add(new EncoderHttpMessageWriter<>(getKotlinSerializationJsonEncoder()));
|
|
||||||
}
|
|
||||||
if (jackson2SmilePresent) {
|
if (jackson2SmilePresent) {
|
||||||
writers.add(new EncoderHttpMessageWriter<>(this.jackson2SmileEncoder != null ?
|
writers.add(new EncoderHttpMessageWriter<>(this.jackson2SmileEncoder != null ?
|
||||||
(Jackson2SmileEncoder) this.jackson2SmileEncoder : new Jackson2SmileEncoder()));
|
(Jackson2SmileEncoder) this.jackson2SmileEncoder : new Jackson2SmileEncoder()));
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,28 @@ public class KotlinSerializationJsonHttpMessageConverter extends AbstractGeneric
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canRead(Type type, @Nullable Class<?> contextClass, @Nullable MediaType mediaType) {
|
||||||
|
try {
|
||||||
|
serializer(GenericTypeResolver.resolveType(type, contextClass));
|
||||||
|
return canRead(mediaType);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canWrite(@Nullable Type type, @Nullable Class<?> clazz, @Nullable MediaType mediaType) {
|
||||||
|
try {
|
||||||
|
serializer(GenericTypeResolver.resolveType(type, clazz));
|
||||||
|
return canWrite(mediaType);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Object read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage)
|
public final Object read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage)
|
||||||
throws IOException, HttpMessageNotReadableException {
|
throws IOException, HttpMessageNotReadableException {
|
||||||
|
|
@ -151,6 +173,7 @@ public class KotlinSerializationJsonHttpMessageConverter extends AbstractGeneric
|
||||||
* Tries to find a serializer that can marshall or unmarshall instances of the given type
|
* Tries to find a serializer that can marshall or unmarshall instances of the given type
|
||||||
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
|
* using kotlinx.serialization. If no serializer can be found, an exception is thrown.
|
||||||
* <p>Resolved serializers are cached and cached results are returned on successive calls.
|
* <p>Resolved serializers are cached and cached results are returned on successive calls.
|
||||||
|
* TODO Avoid relying on throwing exception when https://github.com/Kotlin/kotlinx.serialization/pull/1164 is fixed
|
||||||
* @param type the type to find a serializer for
|
* @param type the type to find a serializer for
|
||||||
* @return a resolved serializer for the given type
|
* @return a resolved serializer for the given type
|
||||||
* @throws RuntimeException if no serializer supporting the given type can be found
|
* @throws RuntimeException if no serializer supporting the given type can be found
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||||
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
||||||
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
||||||
|
import org.springframework.http.codec.json.KotlinSerializationJsonDecoder;
|
||||||
|
import org.springframework.http.codec.json.KotlinSerializationJsonEncoder;
|
||||||
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
|
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
|
||||||
import org.springframework.http.codec.protobuf.ProtobufDecoder;
|
import org.springframework.http.codec.protobuf.ProtobufDecoder;
|
||||||
import org.springframework.http.codec.protobuf.ProtobufHttpMessageWriter;
|
import org.springframework.http.codec.protobuf.ProtobufHttpMessageWriter;
|
||||||
|
|
@ -81,7 +83,7 @@ public class ClientCodecConfigurerTests {
|
||||||
@Test
|
@Test
|
||||||
public void defaultReaders() {
|
public void defaultReaders() {
|
||||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||||
assertThat(readers.size()).isEqualTo(13);
|
assertThat(readers.size()).isEqualTo(14);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
|
||||||
|
|
@ -91,6 +93,7 @@ public class ClientCodecConfigurerTests {
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ProtobufDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ProtobufDecoder.class);
|
||||||
// SPR-16804
|
// SPR-16804
|
||||||
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(FormHttpMessageReader.class);
|
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(FormHttpMessageReader.class);
|
||||||
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationJsonDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
|
||||||
|
|
@ -101,7 +104,7 @@ public class ClientCodecConfigurerTests {
|
||||||
@Test
|
@Test
|
||||||
public void defaultWriters() {
|
public void defaultWriters() {
|
||||||
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
||||||
assertThat(writers.size()).isEqualTo(12);
|
assertThat(writers.size()).isEqualTo(13);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
|
||||||
|
|
@ -110,6 +113,7 @@ public class ClientCodecConfigurerTests {
|
||||||
assertStringEncoder(getNextEncoder(writers), true);
|
assertStringEncoder(getNextEncoder(writers), true);
|
||||||
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ProtobufHttpMessageWriter.class);
|
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ProtobufHttpMessageWriter.class);
|
||||||
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageWriter.class);
|
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageWriter.class);
|
||||||
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationJsonEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
|
||||||
|
|
@ -130,7 +134,7 @@ public class ClientCodecConfigurerTests {
|
||||||
int size = 99;
|
int size = 99;
|
||||||
this.configurer.defaultCodecs().maxInMemorySize(size);
|
this.configurer.defaultCodecs().maxInMemorySize(size);
|
||||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||||
assertThat(readers.size()).isEqualTo(13);
|
assertThat(readers.size()).isEqualTo(14);
|
||||||
assertThat(((ByteArrayDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((ByteArrayDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((ByteBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((ByteBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((DataBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((DataBufferDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
|
@ -140,6 +144,7 @@ public class ClientCodecConfigurerTests {
|
||||||
assertThat(((ProtobufDecoder) getNextDecoder(readers)).getMaxMessageSize()).isEqualTo(size);
|
assertThat(((ProtobufDecoder) getNextDecoder(readers)).getMaxMessageSize()).isEqualTo(size);
|
||||||
assertThat(((FormHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((FormHttpMessageReader) nextReader(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
|
||||||
|
assertThat(((KotlinSerializationJsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((Jackson2JsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((Jackson2JsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((Jackson2SmileDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((Jackson2SmileDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((Jaxb2XmlDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((Jaxb2XmlDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
|
@ -187,7 +192,7 @@ public class ClientCodecConfigurerTests {
|
||||||
writers = findCodec(this.configurer.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
writers = findCodec(this.configurer.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
||||||
|
|
||||||
assertThat(sseDecoder).isNotSameAs(jackson2Decoder);
|
assertThat(sseDecoder).isNotSameAs(jackson2Decoder);
|
||||||
assertThat(writers).hasSize(11);
|
assertThat(writers).hasSize(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // gh-24194
|
@Test // gh-24194
|
||||||
|
|
@ -197,7 +202,7 @@ public class ClientCodecConfigurerTests {
|
||||||
List<HttpMessageWriter<?>> writers =
|
List<HttpMessageWriter<?>> writers =
|
||||||
findCodec(clone.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
findCodec(clone.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
||||||
|
|
||||||
assertThat(writers).hasSize(11);
|
assertThat(writers).hasSize(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -211,7 +216,7 @@ public class ClientCodecConfigurerTests {
|
||||||
List<HttpMessageWriter<?>> writers =
|
List<HttpMessageWriter<?>> writers =
|
||||||
findCodec(clone.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
findCodec(clone.getWriters(), MultipartHttpMessageWriter.class).getPartWriters();
|
||||||
|
|
||||||
assertThat(writers).hasSize(11);
|
assertThat(writers).hasSize(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Decoder<?> getNextDecoder(List<HttpMessageReader<?>> readers) {
|
private Decoder<?> getNextDecoder(List<HttpMessageReader<?>> readers) {
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||||
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
||||||
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
||||||
|
import org.springframework.http.codec.json.KotlinSerializationJsonDecoder;
|
||||||
|
import org.springframework.http.codec.json.KotlinSerializationJsonEncoder;
|
||||||
import org.springframework.http.codec.protobuf.ProtobufDecoder;
|
import org.springframework.http.codec.protobuf.ProtobufDecoder;
|
||||||
import org.springframework.http.codec.protobuf.ProtobufEncoder;
|
import org.springframework.http.codec.protobuf.ProtobufEncoder;
|
||||||
import org.springframework.http.codec.protobuf.ProtobufHttpMessageWriter;
|
import org.springframework.http.codec.protobuf.ProtobufHttpMessageWriter;
|
||||||
|
|
@ -79,7 +81,7 @@ class CodecConfigurerTests {
|
||||||
@Test
|
@Test
|
||||||
void defaultReaders() {
|
void defaultReaders() {
|
||||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||||
assertThat(readers.size()).isEqualTo(12);
|
assertThat(readers.size()).isEqualTo(13);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
|
||||||
|
|
@ -88,6 +90,7 @@ class CodecConfigurerTests {
|
||||||
assertStringDecoder(getNextDecoder(readers), true);
|
assertStringDecoder(getNextDecoder(readers), true);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ProtobufDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ProtobufDecoder.class);
|
||||||
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(FormHttpMessageReader.class);
|
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(FormHttpMessageReader.class);
|
||||||
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationJsonDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
|
||||||
|
|
@ -97,7 +100,7 @@ class CodecConfigurerTests {
|
||||||
@Test
|
@Test
|
||||||
void defaultWriters() {
|
void defaultWriters() {
|
||||||
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
||||||
assertThat(writers.size()).isEqualTo(11);
|
assertThat(writers.size()).isEqualTo(12);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
|
||||||
|
|
@ -105,6 +108,7 @@ class CodecConfigurerTests {
|
||||||
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ResourceHttpMessageWriter.class);
|
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ResourceHttpMessageWriter.class);
|
||||||
assertStringEncoder(getNextEncoder(writers), true);
|
assertStringEncoder(getNextEncoder(writers), true);
|
||||||
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ProtobufHttpMessageWriter.class);
|
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ProtobufHttpMessageWriter.class);
|
||||||
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationJsonEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
|
||||||
|
|
@ -133,7 +137,7 @@ class CodecConfigurerTests {
|
||||||
|
|
||||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||||
|
|
||||||
assertThat(readers.size()).isEqualTo(16);
|
assertThat(readers.size()).isEqualTo(17);
|
||||||
assertThat(getNextDecoder(readers)).isSameAs(customDecoder1);
|
assertThat(getNextDecoder(readers)).isSameAs(customDecoder1);
|
||||||
assertThat(readers.get(this.index.getAndIncrement())).isSameAs(customReader1);
|
assertThat(readers.get(this.index.getAndIncrement())).isSameAs(customReader1);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
||||||
|
|
@ -146,6 +150,7 @@ class CodecConfigurerTests {
|
||||||
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(FormHttpMessageReader.class);
|
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(FormHttpMessageReader.class);
|
||||||
assertThat(getNextDecoder(readers)).isSameAs(customDecoder2);
|
assertThat(getNextDecoder(readers)).isSameAs(customDecoder2);
|
||||||
assertThat(readers.get(this.index.getAndIncrement())).isSameAs(customReader2);
|
assertThat(readers.get(this.index.getAndIncrement())).isSameAs(customReader2);
|
||||||
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationJsonDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
|
||||||
|
|
@ -174,7 +179,7 @@ class CodecConfigurerTests {
|
||||||
|
|
||||||
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
||||||
|
|
||||||
assertThat(writers.size()).isEqualTo(15);
|
assertThat(writers.size()).isEqualTo(16);
|
||||||
assertThat(getNextEncoder(writers)).isSameAs(customEncoder1);
|
assertThat(getNextEncoder(writers)).isSameAs(customEncoder1);
|
||||||
assertThat(writers.get(this.index.getAndIncrement())).isSameAs(customWriter1);
|
assertThat(writers.get(this.index.getAndIncrement())).isSameAs(customWriter1);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
||||||
|
|
@ -186,6 +191,7 @@ class CodecConfigurerTests {
|
||||||
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ProtobufHttpMessageWriter.class);
|
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ProtobufHttpMessageWriter.class);
|
||||||
assertThat(getNextEncoder(writers)).isSameAs(customEncoder2);
|
assertThat(getNextEncoder(writers)).isSameAs(customEncoder2);
|
||||||
assertThat(writers.get(this.index.getAndIncrement())).isSameAs(customWriter2);
|
assertThat(writers.get(this.index.getAndIncrement())).isSameAs(customWriter2);
|
||||||
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationJsonEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||||
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
||||||
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
||||||
|
import org.springframework.http.codec.json.KotlinSerializationJsonDecoder;
|
||||||
|
import org.springframework.http.codec.json.KotlinSerializationJsonEncoder;
|
||||||
import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader;
|
import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader;
|
||||||
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
|
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
|
||||||
import org.springframework.http.codec.multipart.PartHttpMessageWriter;
|
import org.springframework.http.codec.multipart.PartHttpMessageWriter;
|
||||||
|
|
@ -83,7 +85,7 @@ public class ServerCodecConfigurerTests {
|
||||||
@Test
|
@Test
|
||||||
public void defaultReaders() {
|
public void defaultReaders() {
|
||||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||||
assertThat(readers.size()).isEqualTo(14);
|
assertThat(readers.size()).isEqualTo(15);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteArrayDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(ByteBufferDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(DataBufferDecoder.class);
|
||||||
|
|
@ -94,6 +96,7 @@ public class ServerCodecConfigurerTests {
|
||||||
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(FormHttpMessageReader.class);
|
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(FormHttpMessageReader.class);
|
||||||
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(DefaultPartHttpMessageReader.class);
|
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(DefaultPartHttpMessageReader.class);
|
||||||
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageReader.class);
|
assertThat(readers.get(this.index.getAndIncrement()).getClass()).isEqualTo(MultipartHttpMessageReader.class);
|
||||||
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(KotlinSerializationJsonDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2JsonDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jackson2SmileDecoder.class);
|
||||||
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
|
assertThat(getNextDecoder(readers).getClass()).isEqualTo(Jaxb2XmlDecoder.class);
|
||||||
|
|
@ -103,7 +106,7 @@ public class ServerCodecConfigurerTests {
|
||||||
@Test
|
@Test
|
||||||
public void defaultWriters() {
|
public void defaultWriters() {
|
||||||
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
|
||||||
assertThat(writers.size()).isEqualTo(13);
|
assertThat(writers.size()).isEqualTo(14);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteArrayEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(ByteBufferEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(DataBufferEncoder.class);
|
||||||
|
|
@ -112,6 +115,7 @@ public class ServerCodecConfigurerTests {
|
||||||
assertStringEncoder(getNextEncoder(writers), true);
|
assertStringEncoder(getNextEncoder(writers), true);
|
||||||
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ProtobufHttpMessageWriter.class);
|
assertThat(writers.get(index.getAndIncrement()).getClass()).isEqualTo(ProtobufHttpMessageWriter.class);
|
||||||
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartHttpMessageWriter.class);
|
assertThat(writers.get(this.index.getAndIncrement()).getClass()).isEqualTo(PartHttpMessageWriter.class);
|
||||||
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(KotlinSerializationJsonEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2JsonEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jackson2SmileEncoder.class);
|
||||||
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
|
assertThat(getNextEncoder(writers).getClass()).isEqualTo(Jaxb2XmlEncoder.class);
|
||||||
|
|
@ -152,6 +156,7 @@ public class ServerCodecConfigurerTests {
|
||||||
DefaultPartHttpMessageReader reader = (DefaultPartHttpMessageReader) multipartReader.getPartReader();
|
DefaultPartHttpMessageReader reader = (DefaultPartHttpMessageReader) multipartReader.getPartReader();
|
||||||
assertThat((reader).getMaxInMemorySize()).isEqualTo(size);
|
assertThat((reader).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
|
||||||
|
assertThat(((KotlinSerializationJsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((Jackson2JsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((Jackson2JsonDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((Jackson2SmileDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((Jackson2SmileDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
assertThat(((Jaxb2XmlDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
assertThat(((Jaxb2XmlDecoder) getNextDecoder(readers)).getMaxInMemorySize()).isEqualTo(size);
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,11 @@ class KotlinSerializationJsonDecoderTests : AbstractDecoderTests<KotlinSerializa
|
||||||
MediaType("application", "json", StandardCharsets.US_ASCII))).isTrue()
|
MediaType("application", "json", StandardCharsets.US_ASCII))).isTrue()
|
||||||
Assertions.assertThat(decoder.canDecode(ResolvableType.forClass(Pojo::class.java),
|
Assertions.assertThat(decoder.canDecode(ResolvableType.forClass(Pojo::class.java),
|
||||||
MediaType("application", "json", StandardCharsets.ISO_8859_1))).isTrue()
|
MediaType("application", "json", StandardCharsets.ISO_8859_1))).isTrue()
|
||||||
|
|
||||||
|
Assertions.assertThat(decoder.canDecode(ResolvableType.forClassWithGenerics(List::class.java, Int::class.java), MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
Assertions.assertThat(decoder.canDecode(ResolvableType.forClassWithGenerics(List::class.java, Pojo::class.java), MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
Assertions.assertThat(decoder.canDecode(ResolvableType.forClassWithGenerics(ArrayList::class.java, Int::class.java), MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
Assertions.assertThat(decoder.canDecode(ResolvableType.forClassWithGenerics(ArrayList::class.java, Int::class.java), MediaType.APPLICATION_PDF)).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,11 @@ class KotlinSerializationJsonEncoderTests : AbstractEncoderTests<KotlinSerializa
|
||||||
MediaType("application", "json", StandardCharsets.UTF_8))).isTrue()
|
MediaType("application", "json", StandardCharsets.UTF_8))).isTrue()
|
||||||
Assertions.assertThat(encoder.canEncode(ResolvableType.forClass(Pojo::class.java),
|
Assertions.assertThat(encoder.canEncode(ResolvableType.forClass(Pojo::class.java),
|
||||||
MediaType("application", "json", StandardCharsets.US_ASCII))).isTrue()
|
MediaType("application", "json", StandardCharsets.US_ASCII))).isTrue()
|
||||||
Assertions.assertThat(encoder.canEncode(ResolvableType.NONE, null)).isTrue()
|
|
||||||
|
Assertions.assertThat(encoder.canEncode(ResolvableType.forClassWithGenerics(List::class.java, Int::class.java), MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
Assertions.assertThat(encoder.canEncode(ResolvableType.forClassWithGenerics(List::class.java, KotlinSerializationJsonDecoderTests.Pojo::class.java), MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
Assertions.assertThat(encoder.canEncode(ResolvableType.forClassWithGenerics(ArrayList::class.java, Int::class.java), MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
Assertions.assertThat(encoder.canEncode(ResolvableType.forClassWithGenerics(ArrayList::class.java, Int::class.java), MediaType.APPLICATION_PDF)).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ import org.springframework.http.MediaType
|
||||||
import org.springframework.http.MockHttpInputMessage
|
import org.springframework.http.MockHttpInputMessage
|
||||||
import org.springframework.http.MockHttpOutputMessage
|
import org.springframework.http.MockHttpOutputMessage
|
||||||
import org.springframework.http.converter.HttpMessageNotReadableException
|
import org.springframework.http.converter.HttpMessageNotReadableException
|
||||||
|
import java.lang.reflect.ParameterizedType
|
||||||
|
import java.lang.reflect.Type
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import kotlin.reflect.javaType
|
import kotlin.reflect.javaType
|
||||||
import kotlin.reflect.typeOf
|
import kotlin.reflect.typeOf
|
||||||
|
|
@ -34,6 +36,7 @@ import kotlin.reflect.typeOf
|
||||||
* @author Andreas Ahlenstorf
|
* @author Andreas Ahlenstorf
|
||||||
* @author Sebastien Deleuze
|
* @author Sebastien Deleuze
|
||||||
*/
|
*/
|
||||||
|
@Suppress("UsePropertyAccessSyntax")
|
||||||
class KotlinSerializationJsonHttpMessageConverterTests {
|
class KotlinSerializationJsonHttpMessageConverterTests {
|
||||||
|
|
||||||
private val converter = KotlinSerializationJsonHttpMessageConverter()
|
private val converter = KotlinSerializationJsonHttpMessageConverter()
|
||||||
|
|
@ -48,6 +51,11 @@ class KotlinSerializationJsonHttpMessageConverterTests {
|
||||||
assertThat(converter.canRead(Map::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
assertThat(converter.canRead(Map::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
assertThat(converter.canRead(List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
assertThat(converter.canRead(List::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
assertThat(converter.canRead(Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
assertThat(converter.canRead(Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
|
||||||
|
assertThat(converter.canRead(typeTokenOf<List<Int>>(), null, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
assertThat(converter.canRead(typeTokenOf<List<SerializableBean>>(), null, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
assertThat(converter.canRead(typeTokenOf<ArrayList<Int>>(), null, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
assertThat(converter.canRead(typeTokenOf<List<Int>>(), null, MediaType.APPLICATION_PDF)).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -60,6 +68,11 @@ class KotlinSerializationJsonHttpMessageConverterTests {
|
||||||
assertThat(converter.canWrite(Map::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
assertThat(converter.canWrite(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)).isTrue()
|
||||||
assertThat(converter.canWrite(Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
assertThat(converter.canWrite(Set::class.java, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
|
||||||
|
assertThat(converter.canWrite(typeTokenOf<List<Int>>(), null, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
assertThat(converter.canWrite(typeTokenOf<List<SerializableBean>>(), null, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
assertThat(converter.canWrite(typeTokenOf<ArrayList<Int>>(), null, MediaType.APPLICATION_JSON)).isTrue()
|
||||||
|
assertThat(converter.canWrite(typeTokenOf<List<Int>>(), null, MediaType.APPLICATION_PDF)).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -296,4 +309,12 @@ class KotlinSerializationJsonHttpMessageConverterTests {
|
||||||
)
|
)
|
||||||
|
|
||||||
data class NotSerializableBean(val string: String)
|
data class NotSerializableBean(val string: String)
|
||||||
|
|
||||||
|
open class TypeBase<T>
|
||||||
|
|
||||||
|
inline fun <reified T> typeTokenOf(): Type {
|
||||||
|
val base = object : TypeBase<T>() {}
|
||||||
|
val superType = base::class.java.genericSuperclass!!
|
||||||
|
return (superType as ParameterizedType).actualTypeArguments.first()!!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -906,6 +906,9 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kotlinSerializationJsonPresent) {
|
||||||
|
messageConverters.add(new KotlinSerializationJsonHttpMessageConverter());
|
||||||
|
}
|
||||||
if (jackson2Present) {
|
if (jackson2Present) {
|
||||||
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();
|
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();
|
||||||
if (this.applicationContext != null) {
|
if (this.applicationContext != null) {
|
||||||
|
|
@ -919,9 +922,6 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
else if (jsonbPresent) {
|
else if (jsonbPresent) {
|
||||||
messageConverters.add(new JsonbHttpMessageConverter());
|
messageConverters.add(new JsonbHttpMessageConverter());
|
||||||
}
|
}
|
||||||
else if (kotlinSerializationJsonPresent) {
|
|
||||||
messageConverters.add(new KotlinSerializationJsonHttpMessageConverter());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jackson2SmilePresent) {
|
if (jackson2SmilePresent) {
|
||||||
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.smile();
|
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.smile();
|
||||||
|
|
|
||||||
|
|
@ -389,17 +389,13 @@ project for more details.
|
||||||
=== Kotlin multiplatform serialization
|
=== Kotlin multiplatform serialization
|
||||||
|
|
||||||
As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is
|
As of Spring Framework 5.3, https://github.com/Kotlin/kotlinx.serialization[Kotlin multiplatform serialization] is
|
||||||
supported in Spring MVC, Spring WebFlux and Spring Messaging. The builtin support currently only targets JSON format.
|
supported in Spring MVC, Spring WebFlux and Spring Messaging (RSocket). The builtin support currently only targets JSON format.
|
||||||
|
|
||||||
To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] and make sure neither
|
|
||||||
Jackson, GSON or JSONB are in the classpath.
|
|
||||||
|
|
||||||
NOTE: For a typical Spring Boot web application, that can be achieved by excluding `spring-boot-starter-json` dependency.
|
|
||||||
|
|
||||||
In Spring MVC, if you need Jackson, GSON or JSONB for other purposes, you can keep them on the classpath and
|
|
||||||
<<web#mvc-config-message-converters, configure message converters>> to remove `MappingJackson2HttpMessageConverter` and add
|
|
||||||
`KotlinSerializationJsonHttpMessageConverter`.
|
|
||||||
|
|
||||||
|
To enable it, follow https://github.com/Kotlin/kotlinx.serialization#setup[those instructions] to add the related dependency and plugin.
|
||||||
|
With Spring MVC and WebFlux, both Kotlin serialization and Jackson will be configured by default if they are in the classpath since
|
||||||
|
Kotlin serialization is designed to serialize only Kotlin classes annotated with `@Serializable`.
|
||||||
|
With Spring Messaging (RSocket), make sure that neither Jackson, GSON or JSONB are in the classpath if you want automatic configuration,
|
||||||
|
if Jackson is needed configure `KotlinSerializationJsonMessageConverter` manually.
|
||||||
|
|
||||||
== Coroutines
|
== Coroutines
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue