diff --git a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/client/WebClientExtensions.kt b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/client/WebClientExtensions.kt index db9e0b8339..ef4edb4429 100644 --- a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/client/WebClientExtensions.kt +++ b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/client/WebClientExtensions.kt @@ -39,7 +39,6 @@ import reactor.core.publisher.Mono * @author Sebastien Deleuze * @since 5.0 */ -@Suppress("EXTENSION_SHADOWED_BY_MEMBER") inline fun > RequestBodySpec.body(publisher: S): RequestHeadersSpec<*> = body(publisher, object : ParameterizedTypeReference() {}) @@ -98,7 +97,7 @@ inline fun WebClient.ResponseSpec.bodyToFlow(batchSize: Int = * @author Sebastien Deleuze * @since 5.2 */ -suspend fun WebClient.RequestHeadersSpec>.awaitExchange(): ClientResponse = +suspend fun RequestHeadersSpec>.awaitExchange(): ClientResponse = exchange().awaitSingle() /** @@ -107,7 +106,7 @@ suspend fun WebClient.RequestHeadersSpec>.aw * @author Sebastien Deleuze * @since 5.2 */ -inline fun WebClient.RequestBodySpec.body(crossinline supplier: suspend () -> T) +inline fun RequestBodySpec.body(crossinline supplier: suspend () -> T) = body(GlobalScope.mono(Dispatchers.Unconfined) { supplier.invoke() }) /** diff --git a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensions.kt b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensions.kt index e44615da65..b9209816a5 100644 --- a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensions.kt +++ b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensions.kt @@ -106,7 +106,7 @@ suspend fun ServerRequest.awaitMultipartData(): MultiValueMap = * @author Sebastien Deleuze * @since 5.2 */ -suspend fun ServerRequest.awaitPrincipalOrNull(): Principal? = +suspend fun ServerRequest.awaitPrincipal(): Principal? = principal().awaitFirstOrNull() /** diff --git a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensions.kt b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensions.kt index fc5c212e9c..8ed19bca04 100644 --- a/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensions.kt +++ b/spring-webflux/src/main/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensions.kt @@ -44,6 +44,7 @@ inline fun ServerResponse.BodyBuilder.body(publisher: Publishe * @author Sebastien Deleuze * @since 5.0 */ +@Deprecated("Use 'sse().body()' instead.") inline fun ServerResponse.BodyBuilder.bodyToServerSentEvents(publisher: Publisher): Mono = contentType(MediaType.TEXT_EVENT_STREAM).body(publisher, object : ParameterizedTypeReference() {}) @@ -68,6 +69,13 @@ fun ServerResponse.BodyBuilder.xml() = contentType(MediaType.APPLICATION_XML) */ fun ServerResponse.BodyBuilder.html() = contentType(MediaType.TEXT_HTML) +/** + * Shortcut for setting [MediaType.TEXT_EVENT_STREAM] `Content-Type` header. + * @author Sebastien Deleuze + * @since 5.2 + */ +fun ServerResponse.BodyBuilder.sse() = contentType(MediaType.TEXT_EVENT_STREAM) + /** * Coroutines variant of [ServerResponse.HeadersBuilder.build]. * @@ -77,17 +85,16 @@ fun ServerResponse.BodyBuilder.html() = contentType(MediaType.TEXT_HTML) suspend fun ServerResponse.HeadersBuilder>.buildAndAwait(): ServerResponse = build().awaitSingle() - /** * Coroutines [Flow] based extension for [ServerResponse.BodyBuilder.body] providing a - * `body(Flow)` variant. This extension is not subject to type erasure and retains + * `bodyFlowAndAwait(Flow)` variant. This extension is not subject to type erasure and retains * actual generic type arguments. * * @author Sebastien Deleuze - * @since 5.0 + * @since 5.2 */ @FlowPreview -suspend inline fun ServerResponse.BodyBuilder.bodyAndAwait(flow: Flow): ServerResponse = +suspend inline fun ServerResponse.BodyBuilder.bodyFlowAndAwait(flow: Flow): ServerResponse = body(flow.asPublisher(), object : ParameterizedTypeReference() {}).awaitSingle() /** @@ -99,19 +106,6 @@ suspend inline fun ServerResponse.BodyBuilder.bodyAndAwait(flo suspend fun ServerResponse.BodyBuilder.bodyAndAwait(body: Any): ServerResponse = syncBody(body).awaitSingle() -/** - * Coroutines [Flow] based extension for [ServerResponse.BodyBuilder.body] providing a - * `bodyToServerSentEvents(Flow)` variant. This extension is not subject to type - * erasure and retains actual generic type arguments. - * - * @author Sebastien Deleuze - * @since 5.0 - */ -@FlowPreview -suspend inline fun ServerResponse.BodyBuilder.bodyToServerSentEventsAndAwait(flow: Flow): ServerResponse = - contentType(MediaType.TEXT_EVENT_STREAM).body(flow.asPublisher(), object : ParameterizedTypeReference() {}).awaitSingle() - - /** * Coroutines variant of [ServerResponse.BodyBuilder.syncBody] without the sync prefix since it is ok to use it within * another suspendable function. diff --git a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensionsTests.kt b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensionsTests.kt index d840e5b69e..537f007ea7 100644 --- a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensionsTests.kt +++ b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerRequestExtensionsTests.kt @@ -99,7 +99,7 @@ class ServerRequestExtensionsTests { val principal = mockk() every { request.principal() } returns Mono.just(principal) runBlocking { - assertEquals(principal, request.awaitPrincipalOrNull()) + assertEquals(principal, request.awaitPrincipal()) } } diff --git a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensionsTests.kt b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensionsTests.kt index 2108df991b..b8b8882b9e 100644 --- a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensionsTests.kt +++ b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/function/server/ServerResponseExtensionsTests.kt @@ -46,13 +46,6 @@ class ServerResponseExtensionsTests { verify { bodyBuilder.body(body, object : ParameterizedTypeReference>() {}) } } - @Test - fun `BodyBuilder#bodyToServerSentEvents with Publisher and reified type parameters`() { - val body = mockk>>() - bodyBuilder.bodyToServerSentEvents(body) - verify { bodyBuilder.contentType(TEXT_EVENT_STREAM).body(ofType>>(), object : ParameterizedTypeReference>() {}) } - } - @Test fun `BodyBuilder#json`() { bodyBuilder.json() @@ -71,6 +64,12 @@ class ServerResponseExtensionsTests { verify { bodyBuilder.contentType(TEXT_HTML) } } + @Test + fun `BodyBuilder#sse`() { + bodyBuilder.sse() + verify { bodyBuilder.contentType(TEXT_EVENT_STREAM) } + } + @Test fun await() { val response = mockk() @@ -96,30 +95,16 @@ class ServerResponseExtensionsTests { @Test @FlowPreview - fun `BodyBuilder#body with Flow and reified type parameters`() { + fun bodyFlowAndAwait() { val response = mockk() val body = mockk>>() every { bodyBuilder.body(ofType>>()) } returns Mono.just(response) runBlocking { - bodyBuilder.bodyAndAwait(body) + bodyBuilder.bodyFlowAndAwait(body) } verify { bodyBuilder.body(ofType>>(), object : ParameterizedTypeReference>() {}) } } - @Test - @FlowPreview - fun `BodyBuilder#bodyToServerSentEvents with Flow and reified type parameters`() { - val response = mockk() - val body = mockk>>() - every { bodyBuilder.contentType(ofType()) } returns bodyBuilder - every { bodyBuilder.body(ofType>>()) } returns Mono.just(response) - runBlocking { - bodyBuilder.bodyToServerSentEventsAndAwait(body) - } - verify { bodyBuilder.body(ofType>>(), object : ParameterizedTypeReference>() {}) } - verify { bodyBuilder.contentType(TEXT_EVENT_STREAM) } - } - @Test fun `renderAndAwait with a vararg parameter`() { val response = mockk()