diff --git a/spring-web/src/main/kotlin/org/springframework/web/client/RestClientExtensions.kt b/spring-web/src/main/kotlin/org/springframework/web/client/RestClientExtensions.kt new file mode 100644 index 000000000000..9ed98fcad6e4 --- /dev/null +++ b/spring-web/src/main/kotlin/org/springframework/web/client/RestClientExtensions.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.client + +import org.springframework.core.ParameterizedTypeReference +import org.springframework.http.ResponseEntity + +/** + * Extension for [RestClient.RequestBodySpec.body] providing a `bodyWithType(...)` variant + * leveraging Kotlin reified type parameters. This extension is not subject to type + * erasure and retains actual generic type arguments. + * + * @author Sebastien Deleuze + * @since 6.1 + */ +inline fun RestClient.RequestBodySpec.bodyWithType(body: T): RestClient.RequestBodySpec = + body(body, object : ParameterizedTypeReference() {}) + + +/** + * Extension for [RestClient.ResponseSpec.body] providing a `body()` variant + * leveraging Kotlin reified type parameters. This extension is not subject to type + * erasure and retains actual generic type arguments. + * + * @author Sebastien Deleuze + * @since 6.1 + */ +inline fun RestClient.ResponseSpec.body(): T? = + body(object : ParameterizedTypeReference() {}) + + +/** + * Extension for [RestClient.ResponseSpec.toEntity] providing a `toEntity()` variant + * leveraging Kotlin reified type parameters. This extension is not subject to type + * erasure and retains actual generic type arguments. + * + * @author Sebastien Deleuze + * @since 6.1 + */ +inline fun RestClient.ResponseSpec.toEntity(): ResponseEntity = + toEntity(object : ParameterizedTypeReference() {}) diff --git a/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt b/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt new file mode 100644 index 000000000000..8b68868f3281 --- /dev/null +++ b/spring-web/src/test/kotlin/org/springframework/web/client/RestClientExtensionsTests.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.client + +import io.mockk.mockk +import io.mockk.verify +import org.junit.jupiter.api.Test +import org.springframework.core.ParameterizedTypeReference + +/** + * Mock object based tests for [RestClient] Kotlin extensions + * + * @author Sebastien Deleuze + */ +class RestClientExtensionsTests { + + private val requestBodySpec = mockk(relaxed = true) + + private val responseSpec = mockk(relaxed = true) + + @Test + fun `RequestBodySpec#body with reified type parameters`() { + val body = mockk>() + requestBodySpec.bodyWithType(body) + verify { requestBodySpec.body(body, object : ParameterizedTypeReference>() {}) } + } + + @Test + fun `ResponseSpec#body with reified type parameters`() { + responseSpec.body>() + verify { responseSpec.body(object : ParameterizedTypeReference>() {}) } + } + + @Test + fun `ResponseSpec#toEntity with reified type parameters`() { + responseSpec.toEntity>() + verify { responseSpec.toEntity(object : ParameterizedTypeReference>() {}) } + } + + private class Foo + +}