@ -24,6 +24,7 @@ import kotlinx.serialization.Serializable
@@ -24,6 +24,7 @@ import kotlinx.serialization.Serializable
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.jupiter.api.Test
import org.springframework.core.MethodParameter
import kotlin.reflect.javaType
import kotlin.reflect.typeOf
@ -35,6 +36,7 @@ import org.springframework.http.customJson
@@ -35,6 +36,7 @@ import org.springframework.http.customJson
import org.springframework.web.testfixture.http.MockHttpInputMessage
import org.springframework.web.testfixture.http.MockHttpOutputMessage
import java.math.BigDecimal
import kotlin.reflect.jvm.javaMethod
/ * *
* Tests for the JSON conversion using kotlinx . serialization .
@ -55,22 +57,22 @@ class KotlinSerializationJsonHttpMessageConverterTests {
@@ -55,22 +57,22 @@ class KotlinSerializationJsonHttpMessageConverterTests {
assertThat ( converter . canRead ( NotSerializableBean :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( Map :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( typeToken Of< Map < String , SerializableBean > > ( ) , Map :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( resolvableType Of< Map < String , SerializableBean > > ( ) , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( List :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( typeToken Of< List < SerializableBean > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( resolvableType Of< List < SerializableBean > > ( ) , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( Set :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( typeToken Of< Set < SerializableBean > > ( ) , Set :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( resolvableType Of< Set < SerializableBean > > ( ) , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( typeToken Of< List < Int > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( typeToken Of< ArrayList < Int > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( typeToken Of< List < Int > > ( ) , List :: class . java , MediaType . APPLICATION _PDF ) ) . isFalse ( )
assertThat ( converter . canRead ( resolvableType Of< List < Int > > ( ) , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( resolvableType Of< ArrayList < Int > > ( ) , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canRead ( resolvableType Of< List < Int > > ( ) , MediaType . APPLICATION _PDF ) ) . isFalse ( )
assertThat ( converter . canRead ( typeToken Of< Ordered > ( ) , Ordered :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( typeToken Of< List < Ordered > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( resolvableType Of< Ordered > ( ) , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( resolvableType Of< List < Ordered > > ( ) , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( ResolvableType . NONE . type , null , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( ResolvableType . forType ( ResolvableType . NONE . type ) , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( BigDecimal :: class . java , null , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canRead ( ResolvableType . forType ( BigDecimal :: class . java ) , MediaType . APPLICATION _JSON ) ) . isFalse ( )
}
@Test
@ -81,21 +83,21 @@ class KotlinSerializationJsonHttpMessageConverterTests {
@@ -81,21 +83,21 @@ class KotlinSerializationJsonHttpMessageConverterTests {
assertThat ( converter . canWrite ( NotSerializableBean :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canWrite ( Map :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canWrite ( typeToken Of< Map < String , SerializableBean > > ( ) , Map :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( resolvableType Of< Map < String , SerializableBean > > ( ) , Map :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( List :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canWrite ( typeToken Of< List < SerializableBean > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( resolvableType Of< List < SerializableBean > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( Set :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canWrite ( typeToken Of< Set < SerializableBean > > ( ) , Set :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( resolvableType Of< Set < SerializableBean > > ( ) , Set :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( typeToken Of< List < Int > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( typeToken Of< ArrayList < Int > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( typeToken Of< List < Int > > ( ) , List :: class . java , MediaType . APPLICATION _PDF ) ) . isFalse ( )
assertThat ( converter . canWrite ( resolvableType Of< List < Int > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( resolvableType Of< ArrayList < Int > > ( ) , List :: class . java , MediaType . APPLICATION _JSON ) ) . isTrue ( )
assertThat ( converter . canWrite ( resolvableType Of< List < Int > > ( ) , List :: class . java , MediaType . APPLICATION _PDF ) ) . isFalse ( )
assertThat ( converter . canWrite ( typeToken Of< Ordered > ( ) , Ordered :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canWrite ( resolvableType Of< Ordered > ( ) , Ordered :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canWrite ( ResolvableType . NONE . type , SerializableBean :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canWrite ( ResolvableType . NONE , SerializableBean :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canWrite ( BigDecimal :: class . java , BigDecimal :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
assertThat ( converter . canWrite ( ResolvableType . forType ( BigDecimal :: class . java ) , BigDecimal :: class . java , MediaType . APPLICATION _JSON ) ) . isFalse ( )
}
@Test
@ -198,7 +200,7 @@ class KotlinSerializationJsonHttpMessageConverterTests {
@@ -198,7 +200,7 @@ class KotlinSerializationJsonHttpMessageConverterTests {
""" .trimIndent()
val inputMessage = MockHttpInputMessage ( body . toByteArray ( charset ( " UTF-8 " ) ) )
inputMessage . headers . contentType = MediaType . APPLICATION _JSON
val result = converter . read ( typeOf < List < SerializableBean > > ( ) . javaType , null , inputMessage )
val result = converter . read ( ResolvableType . forType ( typeOf < List < SerializableBean > > ( ) . javaType ) , inputMessage , null )
as List < SerializableBean >
assertThat ( result ) . hasSize ( 1 )
@ -234,6 +236,19 @@ class KotlinSerializationJsonHttpMessageConverterTests {
@@ -234,6 +236,19 @@ class KotlinSerializationJsonHttpMessageConverterTests {
}
}
@Test
@Suppress ( " UNCHECKED_CAST " )
fun readNullableWithNull ( ) {
val body = """ {"value":null} """
val inputMessage = MockHttpInputMessage ( body . toByteArray ( StandardCharsets . UTF _8 ) )
inputMessage . headers . contentType = MediaType . APPLICATION _JSON
val methodParameter = MethodParameter . forExecutable ( :: handleMapWithNullable :: javaMethod . get ( ) !! , 0 )
val result = converter . read ( ResolvableType . forMethodParameter ( methodParameter ) , inputMessage , null ) as Map < String , String ? >
assertThat ( result ) . containsExactlyEntriesOf ( mapOf ( " value " to null ) )
}
@Test
fun writeObject ( ) {
val outputMessage = MockHttpOutputMessage ( )
@ -297,8 +312,8 @@ class KotlinSerializationJsonHttpMessageConverterTests {
@@ -297,8 +312,8 @@ class KotlinSerializationJsonHttpMessageConverterTests {
[{"bytes":[1,2] , " array " : [ " Foo " , " Bar " ] , " number " : 42 , " string " : " Foo " , " bool " : true , " fraction " : 42.0 } ]
""" .trimIndent()
this . converter . write ( arrayListOf ( serializableBean ) , typeOf < List < SerializableBean > > ( ) . javaType , null ,
outputMessage )
this . converter . write ( arrayListOf ( serializableBean ) , ResolvableType . forType ( typeOf < List < SerializableBean > > ( ) . javaType ) , null ,
outputMessage , null )
val result = outputMessage . getBodyAsString ( StandardCharsets . UTF _8 )
@ -356,6 +371,23 @@ class KotlinSerializationJsonHttpMessageConverterTests {
@@ -356,6 +371,23 @@ class KotlinSerializationJsonHttpMessageConverterTests {
assertThat ( result ) . isEqualTo ( " 1.0 " )
}
@Test
@ExperimentalStdlibApi
fun writeNullableWithNull ( ) {
val outputMessage = MockHttpOutputMessage ( )
val serializableBean = mapOf < String , String ? > ( " value " to null )
val expectedJson = """ {"value":null} """
val methodParameter = MethodParameter . forExecutable ( :: handleMapWithNullable :: javaMethod . get ( ) !! , - 1 )
this . converter . write ( serializableBean , ResolvableType . forMethodParameter ( methodParameter ) , null ,
outputMessage , null )
val result = outputMessage . getBodyAsString ( StandardCharsets . UTF _8 )
assertThat ( outputMessage . headers ) . containsEntry ( " Content-Type " , listOf ( " application/json " ) )
assertThat ( result ) . isEqualTo ( expectedJson )
}
@Serializable
@Suppress ( " ArrayInDataClass " )
@ -373,10 +405,12 @@ class KotlinSerializationJsonHttpMessageConverterTests {
@@ -373,10 +405,12 @@ class KotlinSerializationJsonHttpMessageConverterTests {
open class TypeBase < T >
inline fun < reified T > typeToken Of( ) : Type {
private inline fun < reified T > resolvableType Of( ) : Resolvable Type {
val base = object : TypeBase < T > ( ) { }
val superType = base :: class . java . genericSuperclass !!
return ( superType as ParameterizedType ) . actualTypeArguments . first ( ) !!
return ResolvableType . forType ( ( superType as ParameterizedType ) . actualTypeArguments . first ( ) !! )
}
fun handleMapWithNullable ( map : Map < String , String ? > ) = map
}