Skip to content

Commit 7a9bd3f

Browse files
committed
Merge branch '5.3.x'
2 parents eb91d21 + b766a49 commit 7a9bd3f

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -129,15 +129,16 @@ public void setReactiveAdapterRegistry(ReactiveAdapterRegistry registry) {
129129
* @param providedArgs optional list of argument values to match by type
130130
* @return a Mono with a {@link HandlerResult}
131131
*/
132-
@SuppressWarnings("KotlinInternalInJava")
132+
@SuppressWarnings({"KotlinInternalInJava", "unchecked"})
133133
public Mono<HandlerResult> invoke(
134134
ServerWebExchange exchange, BindingContext bindingContext, Object... providedArgs) {
135135

136136
return getMethodArgumentValues(exchange, bindingContext, providedArgs).flatMap(args -> {
137137
Object value;
138+
Method method = getBridgedMethod();
139+
boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
138140
try {
139-
Method method = getBridgedMethod();
140-
if (KotlinDetector.isSuspendingFunction(method)) {
141+
if (isSuspendingFunction) {
141142
value = CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args);
142143
}
143144
else {
@@ -163,10 +164,16 @@ public Mono<HandlerResult> invoke(
163164
}
164165

165166
MethodParameter returnType = getReturnType();
166-
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(returnType.getParameterType());
167-
boolean asyncVoid = isAsyncVoidReturnType(returnType, adapter);
168-
if ((value == null || asyncVoid) && isResponseHandled(args, exchange)) {
169-
return (asyncVoid ? Mono.from(adapter.toPublisher(value)) : Mono.empty());
167+
if (isResponseHandled(args, exchange)) {
168+
Class<?> parameterType = returnType.getParameterType();
169+
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(parameterType);
170+
boolean asyncVoid = isAsyncVoidReturnType(returnType, adapter);
171+
if (value == null || asyncVoid) {
172+
return (asyncVoid ? Mono.from(adapter.toPublisher(value)) : Mono.empty());
173+
}
174+
if (isSuspendingFunction && parameterType == void.class) {
175+
return (Mono<HandlerResult>) value;
176+
}
170177
}
171178

172179
HandlerResult result = new HandlerResult(this, value, returnType, bindingContext);

spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/KotlinInvocableHandlerMethodTests.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import org.springframework.web.reactive.result.method.annotation.ContinuationHan
3434
import reactor.core.publisher.Mono
3535
import reactor.test.StepVerifier
3636
import java.lang.reflect.Method
37+
import java.time.Duration
3738
import kotlin.reflect.jvm.javaMethod
3839

3940
class KotlinInvocableHandlerMethodTests {
@@ -89,11 +90,9 @@ class KotlinInvocableHandlerMethodTests {
8990
val response = this.exchange.response
9091
this.resolvers.add(stubResolver(response))
9192
val method = CoroutinesController::response.javaMethod!!
92-
val result = invoke(CoroutinesController(), method)
93+
val result = invokeForResult(CoroutinesController(), method, response)
9394

94-
StepVerifier.create(result)
95-
.consumeNextWith { StepVerifier.create(it.returnValue as Mono<*>).verifyComplete() }
96-
.verifyComplete()
95+
assertThat(result).`as`("Expected no result (i.e. fully handled)").isNull()
9796
assertThat(this.exchange.response.headers.getFirst("foo")).isEqualTo("bar")
9897
}
9998

@@ -105,6 +104,10 @@ class KotlinInvocableHandlerMethodTests {
105104
assertHandlerResultValue(result, "success:foo")
106105
}
107106

107+
private fun invokeForResult(handler: Any, method: Method, vararg providedArgs: Any): HandlerResult? {
108+
return invoke(handler, method, *providedArgs).block(Duration.ofSeconds(5))
109+
}
110+
108111
private fun invoke(handler: Any, method: Method, vararg providedArgs: Any?): Mono<HandlerResult> {
109112
val invocable = InvocableHandlerMethod(handler, method)
110113
invocable.setArgumentResolvers(this.resolvers)

0 commit comments

Comments
 (0)