Use ParameterizedTypeReference instead of Class in Kotlin extensions

This commit also removes WebFlux non-extension functions in favor of
regular Kotlin extensions leveraging ParameterizedTypeReference parameter.

Issue: SPR-15818
This commit is contained in:
Sebastien Deleuze
2017-07-28 00:22:00 +02:00
parent 1d86c9c3d1
commit 6583f9f754
16 changed files with 118 additions and 211 deletions

View File

@@ -294,6 +294,12 @@ class DefaultWebClient implements WebClient {
return this;
}
@Override
public <T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher, ParameterizedTypeReference<T> typeReference) {
this.inserter = BodyInserters.fromPublisher(publisher, typeReference);
return this;
}
@Override
public <T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher, Class<T> elementClass) {
this.inserter = BodyInserters.fromPublisher(publisher, elementClass);

View File

@@ -518,6 +518,19 @@ public interface WebClient {
*/
RequestHeadersSpec<?> body(BodyInserter<?, ? super ClientHttpRequest> inserter);
/**
* Set the body of the request to the given asynchronous {@code Publisher}.
* <p>This method is a convenient shortcut for {@link #body(BodyInserter)} with a
* {@linkplain org.springframework.web.reactive.function.BodyInserters#fromPublisher}
* Publisher body inserter}.
* @param publisher the {@code Publisher} to write to the request
* @param typeReference the type reference of elements contained in the publisher
* @param <T> the type of the elements contained in the publisher
* @param <P> the type of the {@code Publisher}
* @return this builder
*/
<T, P extends Publisher<T>> RequestHeadersSpec<?> body(P publisher, ParameterizedTypeReference<T> typeReference);
/**
* Set the body of the request to the given asynchronous {@code Publisher}.
* <p>This method is a convenient shortcut for {@link #body(BodyInserter)} with a

View File

@@ -1,26 +0,0 @@
package org.springframework.web.reactive.function
import org.springframework.http.ReactiveHttpInputMessage
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
/**
* Function for providing a `bodyToMono()` alternative to `BodyExtractors.toMono(Foo::class.java)`.
*
* @author Sebastien Deleuze
* @since 5.0
* @see [KT-11968](https://youtrack.jetbrains.com/issue/KT-11968)
*/
inline fun <reified T : Any> bodyToMono(): BodyExtractor<Mono<T>, ReactiveHttpInputMessage> =
BodyExtractors.toMono(T::class.java)
/**
* Function for providing a `bodyToFlux()` alternative to `BodyExtractors.toFlux(Foo::class.java)`.
*
* @author Sebastien Deleuze
* @since 5.0
* @see [KT-11968](https://youtrack.jetbrains.com/issue/KT-11968)
*/
inline fun <reified T : Any> bodyToFlux(): BodyExtractor<Flux<T>, ReactiveHttpInputMessage> =
BodyExtractors.toFlux(T::class.java)

View File

@@ -1,39 +0,0 @@
/*
* Copyright 2002-2017 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
*
* http://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.reactive.function
import org.reactivestreams.Publisher
import org.springframework.http.ReactiveHttpOutputMessage
import org.springframework.http.server.reactive.ServerHttpResponse
/**
* Function for providing a `bodyFromPublisher(publisher)` alternative to `BodyInserters.fromPublisher(publisher, Foo::class.java)`.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Publisher<S>, reified S : Any> bodyFromPublisher(publisher: T): BodyInserter<T, ReactiveHttpOutputMessage> =
BodyInserters.fromPublisher(publisher, S::class.java)
/**
* Function for providing a `bodyFromServerSentEvents(publisher)` alternative to `BodyInserters.fromServerSentEvents(publisher, Foo::class.java)`.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Publisher<S>, reified S : Any> bodyFromServerSentEvents(publisher: T): BodyInserter<T, ServerHttpResponse> =
BodyInserters.fromServerSentEvents(publisher, S::class.java)

View File

@@ -16,39 +16,48 @@
package org.springframework.web.reactive.function.client
import org.springframework.core.ParameterizedTypeReference
import org.springframework.http.ResponseEntity
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
/**
* Extension for [ClientResponse.bodyToMono] providing a `bodyToMono<Foo>()` variant.
* Extension for [ClientResponse.bodyToMono] providing a `bodyToMono<Foo>()` variant
* leveraging Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> ClientResponse.bodyToMono(): Mono<T> = bodyToMono(T::class.java)
inline fun <reified T : Any> ClientResponse.bodyToMono(): Mono<T> =
bodyToMono(object : ParameterizedTypeReference<T>() {})
/**
* Extension for [ClientResponse.bodyToFlux] providing a `bodyToFlux<Foo>()` variant.
* Extension for [ClientResponse.bodyToFlux] providing a `bodyToFlux<Foo>()` variant
* leveraging Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> ClientResponse.bodyToFlux(): Flux<T> = bodyToFlux(T::class.java)
inline fun <reified T : Any> ClientResponse.bodyToFlux(): Flux<T> =
bodyToFlux(object : ParameterizedTypeReference<T>() {})
/**
* Extension for [ClientResponse.toEntity] providing a `toEntity<Foo>()` variant.
* Extension for [ClientResponse.toEntity] providing a `toEntity<Foo>()` variant
* leveraging Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> ClientResponse.toEntity(): Mono<ResponseEntity<T>> = toEntity(T::class.java)
inline fun <reified T : Any> ClientResponse.toEntity(): Mono<ResponseEntity<T>> =
toEntity(object : ParameterizedTypeReference<T>() {})
/**
* Extension for [ClientResponse.toEntityList] providing a `bodyToEntityList<Foo>()` variant.
* Extension for [ClientResponse.toEntityList] providing a `bodyToEntityList<Foo>()` variant
* leveraging Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> ClientResponse.toEntityList(): Mono<ResponseEntity<List<T>>> = toEntityList(T::class.java)
inline fun <reified T : Any> ClientResponse.toEntityList(): Mono<ResponseEntity<List<T>>> =
toEntityList(object : ParameterizedTypeReference<T>() {})

View File

@@ -17,34 +17,39 @@
package org.springframework.web.reactive.function.client
import org.reactivestreams.Publisher
import org.springframework.core.ParameterizedTypeReference
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
/**
* Extension for [WebClient.RequestBodySpec.body] providing a variant without explicit class
* parameter thanks to Kotlin reified type parameters.
* Extension for [WebClient.RequestBodySpec.body] providing a `body<Foo>() variant
* leveraging Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 5.0
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
inline fun <reified T : Any, S : Publisher<T>> WebClient.RequestBodySpec.body(publisher: S): WebClient.RequestHeadersSpec<*>
= body(publisher, T::class.java)
inline fun <reified T : Any, S : Publisher<T>> WebClient.RequestBodySpec.body(publisher: S): WebClient.RequestHeadersSpec<*> =
body(publisher, object : ParameterizedTypeReference<T>() {})
/**
* Extension for [WebClient.ResponseSpec.bodyToMono] providing a `bodyToMono<Foo>()` variant.
* Extension for [WebClient.ResponseSpec.bodyToMono] providing a `bodyToMono<Foo>()` variant
* leveraging Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> WebClient.ResponseSpec.bodyToMono(): Mono<T> = bodyToMono(T::class.java)
inline fun <reified T : Any> WebClient.ResponseSpec.bodyToMono(): Mono<T> =
bodyToMono(object : ParameterizedTypeReference<T>() {})
/**
* Extension for [WebClient.ResponseSpec.bodyToFlux] providing a `bodyToFlux<Foo>()` variant.
* Extension for [WebClient.ResponseSpec.bodyToFlux] providing a `bodyToFlux<Foo>()` variant
* leveraging Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> WebClient.ResponseSpec.bodyToFlux(): Flux<T> = bodyToFlux(T::class.java)
inline fun <reified T : Any> WebClient.ResponseSpec.bodyToFlux(): Flux<T> =
bodyToFlux(object : ParameterizedTypeReference<T>() {})

View File

@@ -16,22 +16,27 @@
package org.springframework.web.reactive.function.server
import org.springframework.core.ParameterizedTypeReference
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
/**
* Extension for [ServerRequest.bodyToMono] providing a `bodyToMono<Foo>()` variant.
*
* Extension for [ServerRequest.bodyToMono] providing a `bodyToMono<Foo>()` variant
* leveraging Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> ServerRequest.bodyToMono(): Mono<T> = bodyToMono(T::class.java)
inline fun <reified T : Any> ServerRequest.bodyToMono(): Mono<T> =
bodyToMono(object : ParameterizedTypeReference<T>() {})
/**
* Extension for [ServerRequest.bodyToFlux] providing a `bodyToFlux<Foo>()` variant.
* Extension for [ServerRequest.bodyToFlux] providing a `bodyToFlux<Foo>()` variant
* leveraging Kotlin reified type parameters.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> ServerRequest.bodyToFlux(): Flux<T> = bodyToFlux(T::class.java)
inline fun <reified T : Any> ServerRequest.bodyToFlux(): Flux<T> =
bodyToFlux(object : ParameterizedTypeReference<T>() {})

View File

@@ -17,6 +17,8 @@
package org.springframework.web.reactive.function.server
import org.reactivestreams.Publisher
import org.springframework.core.ParameterizedTypeReference
import org.springframework.http.MediaType
import reactor.core.publisher.Mono
/**
@@ -25,4 +27,14 @@ import reactor.core.publisher.Mono
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> ServerResponse.BodyBuilder.body(publisher: Publisher<T>): Mono<ServerResponse> = body(publisher, T::class.java)
inline fun <reified T : Any> ServerResponse.BodyBuilder.body(publisher: Publisher<T>): Mono<ServerResponse> =
body(publisher, object : ParameterizedTypeReference<T>() {})
/**
* Extension for [ServerResponse.BodyBuilder.body] providing a `bodyToServerSentEvents(Publisher<T>)` variant.
*
* @author Sebastien Deleuze
* @since 5.0
*/
inline fun <reified T : Any> ServerResponse.BodyBuilder.bodyToServerSentEvents(publisher: Publisher<T>): Mono<ServerResponse> =
contentType(MediaType.TEXT_EVENT_STREAM).body(publisher, object : ParameterizedTypeReference<T>() {})