diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java index d856aa160215640f4375cb5620ed2dfadab0fd09..5c8752da4e86d834fe66fac5a79b9bba3cbfb1eb 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapter.java @@ -70,6 +70,35 @@ public class ReactiveAdapter { return this.descriptor; } + /** + * A shortcut for {@code getDescriptor().getReactiveType()}. + */ + public Class getReactiveType() { + return getDescriptor().getReactiveType(); + } + + /** + * A shortcut for {@code getDescriptor().isMultiValue()}. + */ + public boolean isMultiValue() { + return getDescriptor().isMultiValue(); + } + + /** + * A shortcut for {@code getDescriptor().supportsEmpty()}. + */ + public boolean supportsEmpty() { + return getDescriptor().supportsEmpty(); + } + + /** + * A shortcut for {@code getDescriptor().isNoValue()}. + */ + public boolean isNoValue() { + return getDescriptor().isNoValue(); + } + + /** * Adapt the given instance to a Reactive Streams Publisher. * @param source the source object to adapt from diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index 5cf10f1618f957f847146e5f7db28213c66ca8cf..37145b006eaf368e6ae64e660b03f326271414f4 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.Function; -import java.util.function.Predicate; import io.reactivex.BackpressureStrategy; import io.reactivex.Completable; @@ -101,34 +100,31 @@ public class ReactiveAdapterRegistry { } /** - * Get the adapter to use to adapt from the given reactive type. + * Get the adapter for the given reactive type. */ - public ReactiveAdapter getAdapterFrom(Class reactiveType) { - return getAdapterFrom(reactiveType, null); + public ReactiveAdapter getAdapter(Class reactiveType) { + return getAdapter(reactiveType, null); } /** - * Get the adapter to use to adapt from the given reactive type. Or if the - * "source" object is not {@code null} its actual type is used instead. + * Get the adapter for the given reactive type. Or if a "source" object is + * provided, its actual type is used instead. + * @param reactiveType the reactive type + * @param source an instance of the reactive type (i.e. to adapt from) */ - public ReactiveAdapter getAdapterFrom(Class reactiveType, Object source) { + public ReactiveAdapter getAdapter(Class reactiveType, Object source) { + source = (source instanceof Optional ? ((Optional) source).orElse(null) : source); Class clazz = (source != null ? source.getClass() : reactiveType); - return getAdapter(type -> type.isAssignableFrom(clazz)); - } - - /** - * Get the adapter for the given reactive type to adapt to. - */ - public ReactiveAdapter getAdapterTo(Class reactiveType) { - return getAdapter(reactiveType::equals); - } - private ReactiveAdapter getAdapter(Predicate> predicate) { return this.adapters.stream() - .filter(adapter -> predicate.test(adapter.getDescriptor().getReactiveType())) + .filter(adapter -> adapter.getReactiveType().equals(clazz)) .findFirst() - .orElse(null); + .orElseGet(() -> + this.adapters.stream() + .filter(adapter -> adapter.getReactiveType().isAssignableFrom(clazz)) + .findFirst() + .orElse(null)); } @@ -233,7 +229,7 @@ public class ReactiveAdapterRegistry { @Override public Publisher toPublisher(Object source) { Publisher publisher = super.toPublisher(source); - return (getDescriptor().isMultiValue() ? Flux.from(publisher) : Mono.from(publisher)); + return (isMultiValue() ? Flux.from(publisher) : Mono.from(publisher)); } } diff --git a/spring-core/src/test/java/org/springframework/core/convert/support/ReactiveAdapterRegistryTests.java b/spring-core/src/test/java/org/springframework/core/convert/support/ReactiveAdapterRegistryTests.java index 6be82a63a1799457ca6ba126f3cc3954ad75cff0..1271c34392610513e99d73d3a625f82c3d7cf80c 100644 --- a/spring-core/src/test/java/org/springframework/core/convert/support/ReactiveAdapterRegistryTests.java +++ b/spring-core/src/test/java/org/springframework/core/convert/support/ReactiveAdapterRegistryTests.java @@ -25,6 +25,7 @@ import org.junit.Before; import org.junit.Test; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; +import reactor.core.publisher.FluxProcessor; import reactor.core.publisher.Mono; import rx.Completable; import rx.Observable; @@ -32,10 +33,13 @@ import rx.Single; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; +import org.springframework.core.ReactiveTypeDescriptor; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; /** @@ -55,33 +59,55 @@ public class ReactiveAdapterRegistryTests { @Test - public void getDefaultAdapters() throws Exception { + public void defaultAdapterRegistrations() throws Exception { // Reactor - assertNotNull(getAdapterTo(Mono.class)); - assertNotNull(getAdapterTo(Flux.class)); + assertNotNull(getAdapter(Mono.class)); + assertNotNull(getAdapter(Flux.class)); - assertNotNull(getAdapterTo(Publisher.class)); - assertNotNull(getAdapterTo(CompletableFuture.class)); + // Publisher + assertNotNull(getAdapter(Publisher.class)); + + // Completable + assertNotNull(getAdapter(CompletableFuture.class)); // RxJava 1 - assertNotNull(getAdapterTo(Observable.class)); - assertNotNull(getAdapterTo(Single.class)); - assertNotNull(getAdapterTo(Completable.class)); + assertNotNull(getAdapter(Observable.class)); + assertNotNull(getAdapter(Single.class)); + assertNotNull(getAdapter(Completable.class)); // RxJava 2 - assertNotNull(getAdapterTo(Flowable.class)); - assertNotNull(getAdapterTo(io.reactivex.Observable.class)); - assertNotNull(getAdapterTo(io.reactivex.Single.class)); - assertNotNull(getAdapterTo(Maybe.class)); - assertNotNull(getAdapterTo(io.reactivex.Completable.class)); + assertNotNull(getAdapter(Flowable.class)); + assertNotNull(getAdapter(io.reactivex.Observable.class)); + assertNotNull(getAdapter(io.reactivex.Single.class)); + assertNotNull(getAdapter(Maybe.class)); + assertNotNull(getAdapter(io.reactivex.Completable.class)); + } + + @Test + public void getAdapterForReactiveSubType() throws Exception { + + ReactiveAdapter adapter1 = getAdapter(Flux.class); + ReactiveAdapter adapter2 = getAdapter(FluxProcessor.class); + + assertSame(adapter1, adapter2); + + this.registry.registerReactiveType( + ReactiveTypeDescriptor.multiValue(FluxProcessor.class, FluxProcessor::empty), + o -> (FluxProcessor) o, + FluxProcessor::from); + + ReactiveAdapter adapter3 = getAdapter(FluxProcessor.class); + + assertNotNull(adapter3); + assertNotSame(adapter1, adapter3); } @Test public void publisherToFlux() throws Exception { List sequence = Arrays.asList(1, 2, 3); Publisher source = Flowable.fromIterable(sequence); - Object target = getAdapterTo(Flux.class).fromPublisher(source); + Object target = getAdapter(Flux.class).fromPublisher(source); assertTrue(target instanceof Flux); assertEquals(sequence, ((Flux) target).collectList().blockMillis(1000)); } @@ -91,7 +117,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToMono() throws Exception { Publisher source = Flowable.fromArray(1, 2, 3); - Object target = getAdapterTo(Mono.class).fromPublisher(source); + Object target = getAdapter(Mono.class).fromPublisher(source); assertTrue(target instanceof Mono); assertEquals(new Integer(1), ((Mono) target).blockMillis(1000)); } @@ -99,7 +125,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToCompletableFuture() throws Exception { Publisher source = Flowable.fromArray(1, 2, 3); - Object target = getAdapterTo(CompletableFuture.class).fromPublisher(source); + Object target = getAdapter(CompletableFuture.class).fromPublisher(source); assertTrue(target instanceof CompletableFuture); assertEquals(new Integer(1), ((CompletableFuture) target).get()); } @@ -108,7 +134,7 @@ public class ReactiveAdapterRegistryTests { public void publisherToRxObservable() throws Exception { List sequence = Arrays.asList(1, 2, 3); Publisher source = Flowable.fromIterable(sequence); - Object target = getAdapterTo(rx.Observable.class).fromPublisher(source); + Object target = getAdapter(rx.Observable.class).fromPublisher(source); assertTrue(target instanceof rx.Observable); assertEquals(sequence, ((rx.Observable) target).toList().toBlocking().first()); } @@ -116,7 +142,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToRxSingle() throws Exception { Publisher source = Flowable.fromArray(1); - Object target = getAdapterTo(rx.Single.class).fromPublisher(source); + Object target = getAdapter(rx.Single.class).fromPublisher(source); assertTrue(target instanceof rx.Single); assertEquals(new Integer(1), ((rx.Single) target).toBlocking().value()); } @@ -124,7 +150,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToRxCompletable() throws Exception { Publisher source = Flowable.fromArray(1, 2, 3); - Object target = getAdapterTo(rx.Completable.class).fromPublisher(source); + Object target = getAdapter(rx.Completable.class).fromPublisher(source); assertTrue(target instanceof rx.Completable); assertNull(((rx.Completable) target).get()); } @@ -133,7 +159,7 @@ public class ReactiveAdapterRegistryTests { public void publisherToReactivexFlowable() throws Exception { List sequence = Arrays.asList(1, 2, 3); Publisher source = Flux.fromIterable(sequence); - Object target = getAdapterTo(io.reactivex.Flowable.class).fromPublisher(source); + Object target = getAdapter(io.reactivex.Flowable.class).fromPublisher(source); assertTrue(target instanceof io.reactivex.Flowable); assertEquals(sequence, ((io.reactivex.Flowable) target).toList().blockingGet()); } @@ -142,7 +168,7 @@ public class ReactiveAdapterRegistryTests { public void publisherToReactivexObservable() throws Exception { List sequence = Arrays.asList(1, 2, 3); Publisher source = Flowable.fromIterable(sequence); - Object target = getAdapterTo(io.reactivex.Observable.class).fromPublisher(source); + Object target = getAdapter(io.reactivex.Observable.class).fromPublisher(source); assertTrue(target instanceof io.reactivex.Observable); assertEquals(sequence, ((io.reactivex.Observable) target).toList().blockingGet()); } @@ -150,7 +176,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToReactivexSingle() throws Exception { Publisher source = Flowable.fromArray(1); - Object target = getAdapterTo(io.reactivex.Single.class).fromPublisher(source); + Object target = getAdapter(io.reactivex.Single.class).fromPublisher(source); assertTrue(target instanceof io.reactivex.Single); assertEquals(new Integer(1), ((io.reactivex.Single) target).blockingGet()); } @@ -158,7 +184,7 @@ public class ReactiveAdapterRegistryTests { @Test public void publisherToReactivexCompletable() throws Exception { Publisher source = Flowable.fromArray(1, 2, 3); - Object target = getAdapterTo(io.reactivex.Completable.class).fromPublisher(source); + Object target = getAdapter(io.reactivex.Completable.class).fromPublisher(source); assertTrue(target instanceof io.reactivex.Completable); assertNull(((io.reactivex.Completable) target).blockingGet()); } @@ -167,7 +193,7 @@ public class ReactiveAdapterRegistryTests { public void rxObservableToPublisher() throws Exception { List sequence = Arrays.asList(1, 2, 3); Object source = rx.Observable.from(sequence); - Object target = getAdapterFrom(rx.Observable.class).toPublisher(source); + Object target = getAdapter(rx.Observable.class).toPublisher(source); assertTrue("Expected Flux Publisher: " + target.getClass().getName(), target instanceof Flux); assertEquals(sequence, ((Flux) target).collectList().blockMillis(1000)); } @@ -175,7 +201,7 @@ public class ReactiveAdapterRegistryTests { @Test public void rxSingleToPublisher() throws Exception { Object source = rx.Single.just(1); - Object target = getAdapterFrom(rx.Single.class).toPublisher(source); + Object target = getAdapter(rx.Single.class).toPublisher(source); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); assertEquals(new Integer(1), ((Mono) target).blockMillis(1000)); } @@ -183,7 +209,7 @@ public class ReactiveAdapterRegistryTests { @Test public void rxCompletableToPublisher() throws Exception { Object source = rx.Completable.complete(); - Object target = getAdapterFrom(rx.Completable.class).toPublisher(source); + Object target = getAdapter(rx.Completable.class).toPublisher(source); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); ((Mono) target).blockMillis(1000); } @@ -192,7 +218,7 @@ public class ReactiveAdapterRegistryTests { public void reactivexFlowableToPublisher() throws Exception { List sequence = Arrays.asList(1, 2, 3); Object source = io.reactivex.Flowable.fromIterable(sequence); - Object target = getAdapterFrom(io.reactivex.Flowable.class).toPublisher(source); + Object target = getAdapter(io.reactivex.Flowable.class).toPublisher(source); assertTrue("Expected Flux Publisher: " + target.getClass().getName(), target instanceof Flux); assertEquals(sequence, ((Flux) target).collectList().blockMillis(1000)); } @@ -201,7 +227,7 @@ public class ReactiveAdapterRegistryTests { public void reactivexObservableToPublisher() throws Exception { List sequence = Arrays.asList(1, 2, 3); Object source = io.reactivex.Observable.fromIterable(sequence); - Object target = getAdapterFrom(io.reactivex.Observable.class).toPublisher(source); + Object target = getAdapter(io.reactivex.Observable.class).toPublisher(source); assertTrue("Expected Flux Publisher: " + target.getClass().getName(), target instanceof Flux); assertEquals(sequence, ((Flux) target).collectList().blockMillis(1000)); } @@ -209,7 +235,7 @@ public class ReactiveAdapterRegistryTests { @Test public void reactivexSingleToPublisher() throws Exception { Object source = io.reactivex.Single.just(1); - Object target = getAdapterFrom(io.reactivex.Single.class).toPublisher(source); + Object target = getAdapter(io.reactivex.Single.class).toPublisher(source); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); assertEquals(new Integer(1), ((Mono) target).blockMillis(1000)); } @@ -217,7 +243,7 @@ public class ReactiveAdapterRegistryTests { @Test public void reactivexCompletableToPublisher() throws Exception { Object source = io.reactivex.Completable.complete(); - Object target = getAdapterFrom(io.reactivex.Completable.class).toPublisher(source); + Object target = getAdapter(io.reactivex.Completable.class).toPublisher(source); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); ((Mono) target).blockMillis(1000); } @@ -226,18 +252,14 @@ public class ReactiveAdapterRegistryTests { public void CompletableFutureToPublisher() throws Exception { CompletableFuture future = new CompletableFuture(); future.complete(1); - Object target = getAdapterFrom(CompletableFuture.class).toPublisher(future); + Object target = getAdapter(CompletableFuture.class).toPublisher(future); assertTrue("Expected Mono Publisher: " + target.getClass().getName(), target instanceof Mono); assertEquals(new Integer(1), ((Mono) target).blockMillis(1000)); } - private ReactiveAdapter getAdapterTo(Class reactiveType) { - return this.registry.getAdapterTo(reactiveType); - } - - private ReactiveAdapter getAdapterFrom(Class reactiveType) { - return this.registry.getAdapterFrom(reactiveType); + private ReactiveAdapter getAdapter(Class reactiveType) { + return this.registry.getAdapter(reactiveType); } } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java index c5c11b3b77069409436f62a96f522e49ed6a901f..8f82dd27de3b9cfe7ac6635afc37a38ee8fd3986 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageReaderArgumentResolver.java @@ -112,7 +112,7 @@ public abstract class AbstractMessageReaderArgumentResolver { BindingContext bindingContext, ServerWebExchange exchange) { ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParameter); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterTo(bodyType.resolve()); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(bodyType.resolve()); ResolvableType elementType = ResolvableType.forMethodParameter(bodyParameter); if (adapter != null) { @@ -130,7 +130,7 @@ public abstract class AbstractMessageReaderArgumentResolver { if (reader.canRead(elementType, mediaType)) { Map readHints = Collections.emptyMap(); - if (adapter != null && adapter.getDescriptor().isMultiValue()) { + if (adapter != null && adapter.isMultiValue()) { Flux flux; if (reader instanceof ServerHttpMessageReader) { ServerHttpMessageReader serverReader = ((ServerHttpMessageReader) reader); @@ -186,7 +186,7 @@ public abstract class AbstractMessageReaderArgumentResolver { } protected boolean checkRequired(ReactiveAdapter adapter, boolean isBodyRequired) { - return adapter != null && !adapter.getDescriptor().supportsEmpty() || isBodyRequired; + return adapter != null && !adapter.supportsEmpty() || isBodyRequired; } protected ServerWebInputException getRequiredBodyError(MethodParameter parameter) { diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java index 1ffcf87d39e1b4635802c9c865d8f8a0dce17157..5aaa381a07b8261a01c114ab8d81341c2f1e2676 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java @@ -95,19 +95,19 @@ public abstract class AbstractMessageWriterResultHandler extends AbstractHandler ResolvableType valueType = ResolvableType.forMethodParameter(bodyParameter); Class valueClass = valueType.resolve(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(valueClass, body); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(valueClass, body); Publisher publisher; ResolvableType elementType; if (adapter != null) { publisher = adapter.toPublisher(body); - elementType = adapter.getDescriptor().isNoValue() ? - ResolvableType.forClass(Void.class) : - valueType.getGeneric(0); + elementType = adapter.isNoValue() ? + ResolvableType.forClass(Void.class) : valueType.getGeneric(0); } else { publisher = Mono.justOrEmpty(body); - elementType = (valueClass == null && body != null ? ResolvableType.forInstance(body) : valueType); + elementType = (valueClass == null && body != null ? + ResolvableType.forInstance(body) : valueType); } if (void.class == elementType.getRawClass() || Void.class == elementType.getRawClass()) { diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/BindingContextFactory.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/BindingContextFactory.java index 93609de35105df760c8a841253c22cbcaf879a1e..4e6f677fe04bfaa9d9261b391f09f48e8ef4aeae 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/BindingContextFactory.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/BindingContextFactory.java @@ -145,7 +145,7 @@ class BindingContextFactory { } ResolvableType type = result.getReturnType(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(type.getRawClass(), value); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type.getRawClass(), value); Class valueType = (adapter != null ? type.resolveGeneric(0) : type.resolve()); if (Void.class.equals(valueType) || void.class.equals(valueType)) { diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java index 06bd277e35f97d769ea54b2ba9ed2cfda55c8e49..6318cb3b54417fc057b4991d5afa6a12a9c8bf8e 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ErrorsMethodArgumentResolver.java @@ -102,9 +102,9 @@ public class ErrorsMethodArgumentResolver implements HandlerMethodArgumentResolv Class attributeType = attributeParam.getParameterType(); ResolvableType type = ResolvableType.forMethodParameter(attributeParam); - ReactiveAdapter adapterTo = getAdapterRegistry().getAdapterTo(type.resolve()); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type.resolve()); - Assert.isNull(adapterTo, "Errors/BindingResult cannot be used with an async model attribute. " + + Assert.isNull(adapter, "Errors/BindingResult cannot be used with an async model attribute. " + "Either declare the model attribute without the async wrapper type " + "or handle WebExchangeBindException through the async type."); diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java index ddd3229bccdfc87d051cdcae03f0726946d82efa..6ac46ad8b71857b3f1d0437abb3ad0d3ffe7f22e 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ModelAttributeMethodArgumentResolver.java @@ -105,10 +105,9 @@ public class ModelAttributeMethodArgumentResolver implements HandlerMethodArgume } if (this.useDefaultResolution) { Class clazz = parameter.getParameterType(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(clazz); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(clazz); if (adapter != null) { - ReactiveTypeDescriptor descriptor = adapter.getDescriptor(); - if (descriptor.isNoValue() || descriptor.isMultiValue()) { + if (adapter.isNoValue() || adapter.isMultiValue()) { return false; } clazz = ResolvableType.forMethodParameter(parameter).getGeneric(0).getRawClass(); @@ -123,8 +122,8 @@ public class ModelAttributeMethodArgumentResolver implements HandlerMethodArgume ServerWebExchange exchange) { ResolvableType type = ResolvableType.forMethodParameter(parameter); - ReactiveAdapter adapterTo = getAdapterRegistry().getAdapterTo(type.resolve()); - Class valueType = (adapterTo != null ? type.resolveGeneric(0) : parameter.getParameterType()); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type.resolve()); + Class valueType = (adapter != null ? type.resolveGeneric(0) : parameter.getParameterType()); String name = getAttributeName(valueType, parameter); Mono valueMono = getAttributeMono(name, valueType, parameter, context, exchange); @@ -145,8 +144,8 @@ public class ModelAttributeMethodArgumentResolver implements HandlerMethodArgume }) .then(Mono.fromCallable(() -> { BindingResult errors = binder.getBindingResult(); - if (adapterTo != null) { - return adapterTo.fromPublisher(errors.hasErrors() ? + if (adapter != null) { + return adapter.fromPublisher(errors.hasErrors() ? Mono.error(new WebExchangeBindException(parameter, errors)) : Mono.just(value)); } @@ -177,10 +176,9 @@ public class ModelAttributeMethodArgumentResolver implements HandlerMethodArgume attribute = createAttribute(attributeName, attributeType, param, context, exchange); } if (attribute != null) { - ReactiveAdapter adapterFrom = getAdapterRegistry().getAdapterFrom(null, attribute); + ReactiveAdapter adapterFrom = getAdapterRegistry().getAdapter(null, attribute); if (adapterFrom != null) { - ReactiveTypeDescriptor descriptor = adapterFrom.getDescriptor(); - Assert.isTrue(!descriptor.isMultiValue(), "Data binding supports single-value async types."); + Assert.isTrue(!adapterFrom.isMultiValue(), "Data binding supports single-value async types."); return Mono.from(adapterFrom.toPublisher(attribute)); } } diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java index ad635480a03f873091d31ee32e2be24a3b17fae3..7d0a403882a33ee4bfd02b6bbbc213db8c91d7d1 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseBodyResultHandler.java @@ -17,7 +17,6 @@ package org.springframework.web.reactive.result.method.annotation; import java.util.List; -import java.util.Optional; import reactor.core.publisher.Mono; @@ -103,8 +102,8 @@ public class ResponseBodyResultHandler extends AbstractMessageWriterResultHandle return true; } else { - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(rawClass, result.getReturnValue()); - if (adapter != null && !adapter.getDescriptor().isNoValue()) { + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(rawClass, result.getReturnValue()); + if (adapter != null && !adapter.isNoValue()) { ResolvableType genericType = result.getReturnType().getGeneric(0); if (HttpEntity.class.isAssignableFrom(genericType.getRawClass())) { return true; diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java index b62ffea09eca08d28ac4305105acd1eb44d1e160..64d97e958129b659bded40849d1c26e29145dcfc 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java @@ -25,7 +25,6 @@ import reactor.core.publisher.Mono; import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; -import org.springframework.core.ReactiveTypeDescriptor; import org.springframework.core.ResolvableType; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -91,11 +90,8 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand return true; } else { - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(returnType, result.getReturnValue()); - if (adapter != null && - !adapter.getDescriptor().isMultiValue() && - !adapter.getDescriptor().isNoValue()) { - + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(returnType, result.getReturnValue()); + if (adapter != null && !adapter.isMultiValue() && !adapter.isNoValue()) { ResolvableType genericType = result.getReturnType().getGeneric(0); return isSupportedType(genericType.getRawClass()); } @@ -118,11 +114,10 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand Optional optionalValue = result.getReturnValue(); Class rawClass = returnType.getRawClass(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(rawClass, optionalValue); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(rawClass, optionalValue); if (adapter != null) { - ReactiveTypeDescriptor descriptor = adapter.getDescriptor(); - Assert.isTrue(!descriptor.isMultiValue(), "Only a single ResponseEntity supported."); + Assert.isTrue(!adapter.isMultiValue(), "Only a single ResponseEntity supported."); returnValueMono = Mono.from(adapter.toPublisher(optionalValue)); bodyType = new MethodParameter(result.getReturnTypeSource()); bodyType.increaseNestingLevel(); diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java index b0b53a355f64f35af987986b7300d245ed2e047d..184d4c81de7d3e961e2a65a28439559f52231591 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java @@ -33,7 +33,6 @@ import org.springframework.core.MethodParameter; import org.springframework.core.Ordered; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; -import org.springframework.core.ReactiveTypeDescriptor; import org.springframework.core.ResolvableType; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.http.MediaType; @@ -154,9 +153,9 @@ public class ViewResolutionResultHandler extends AbstractHandlerResultHandler return true; } Optional optional = result.getReturnValue(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(clazz, optional); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(clazz, optional); if (adapter != null) { - if (adapter.getDescriptor().isNoValue()) { + if (adapter.isNoValue()) { return true; } else { @@ -190,15 +189,14 @@ public class ViewResolutionResultHandler extends AbstractHandlerResultHandler ResolvableType parameterType = result.getReturnType(); Optional optional = result.getReturnValue(); - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(parameterType.getRawClass(), optional); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameterType.getRawClass(), optional); if (adapter != null) { - ReactiveTypeDescriptor descriptor = adapter.getDescriptor(); - Assert.isTrue(!descriptor.isMultiValue(), "Only single-value async return type supported."); + Assert.isTrue(!adapter.isMultiValue(), "Only single-value async return type supported."); returnValueMono = optional .map(value -> Mono.from(adapter.toPublisher(value))) .orElse(Mono.empty()); - elementType = !adapter.getDescriptor().isNoValue() ? + elementType = !adapter.isNoValue() ? parameterType.getGeneric(0) : ResolvableType.forClass(Void.class); } else { @@ -301,10 +299,10 @@ public class ViewResolutionResultHandler extends AbstractHandlerResultHandler List> valueMonos = new ArrayList<>(); for (Map.Entry entry : model.entrySet()) { - ReactiveAdapter adapter = getAdapterRegistry().getAdapterFrom(null, entry.getValue()); + ReactiveAdapter adapter = getAdapterRegistry().getAdapter(null, entry.getValue()); if (adapter != null) { names.add(entry.getKey()); - if (adapter.getDescriptor().isMultiValue()) { + if (adapter.isMultiValue()) { Flux value = Flux.from(adapter.toPublisher(entry.getValue())); valueMonos.add(value.collectList().defaultIfEmpty(Collections.emptyList())); }