From cef1b7ea6d9197452260db00d1747b39f84bc8e5 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Mon, 12 Aug 2024 21:00:17 +0300 Subject: [PATCH] Polishing in HTTP interface argument resolvers --- .../ROOT/pages/integration/rest-clients.adoc | 8 +++++--- framework-docs/modules/ROOT/pages/rsocket.adoc | 5 +++-- .../rsocket/service/PayloadArgumentResolver.java | 14 +++++++------- .../invoker/HttpMethodArgumentResolver.java | 1 + .../invoker/RequestBodyArgumentResolver.java | 4 ++-- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc index 969d12c44e..edaa51c36e 100644 --- a/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc +++ b/framework-docs/modules/ROOT/pages/integration/rest-clients.adoc @@ -978,11 +978,13 @@ method parameters: `MultiValueMap` with multiple cookies, a `Collection` of values, or an individual value. Type conversion is supported for non-String values. -The parameters can't be null unless they are set as not required through the annotation, -annotated with `@Nullable` or they are `Optional`. - |=== +Method parameters cannot be `null` unless the `required` attribute (where available on a +parameter annotation) is set to `false`, or the parameter is marked optional as determined by +{spring-framework-api}/core/MethodParameter.html#isOptional()[`MethodParameter#isOptional`]. + + [[rest-http-interface-return-values]] === Return Values diff --git a/framework-docs/modules/ROOT/pages/rsocket.adoc b/framework-docs/modules/ROOT/pages/rsocket.adoc index 6a6654a314..8723c7bf40 100644 --- a/framework-docs/modules/ROOT/pages/rsocket.adoc +++ b/framework-docs/modules/ROOT/pages/rsocket.adoc @@ -1115,8 +1115,9 @@ method parameters: | `@Payload` | Set the input payload(s) for the request. This can be a concrete value, or any producer of values that can be adapted to a Reactive Streams `Publisher` via - `ReactiveAdapterRegistry`. The payload can't be null unless it's set as not required -through the annotation, annotated with `@Nullable` or it is `Optional`. + `ReactiveAdapterRegistry`. A payload must be provided unless the `required` attribute + is set to `false`, or the parameter is marked optional as determined by + {spring-framework-api}/core/MethodParameter.html#isOptional()[`MethodParameter#isOptional`]. | `Object`, if followed by `MimeType` | The value for a metadata entry in the input payload. This can be any `Object` as long diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/service/PayloadArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/service/PayloadArgumentResolver.java index e8081efced..b80c747bbd 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/service/PayloadArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/service/PayloadArgumentResolver.java @@ -56,14 +56,13 @@ public class PayloadArgumentResolver implements RSocketServiceArgumentResolver { } if (argument == null) { - boolean required = (annot == null || annot.required()) && !parameter.isOptional(); - Assert.isTrue(!required, () -> "Missing payload"); + boolean isOptional = ((annot != null && !annot.required()) || parameter.isOptional()); + Assert.isTrue(isOptional, () -> "Missing payload"); return true; } - ReactiveAdapter reactiveAdapter = this.reactiveAdapterRegistry - .getAdapter(parameter.getParameterType()); - if (reactiveAdapter == null) { + ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(parameter.getParameterType()); + if (adapter == null) { requestValues.setPayloadValue(argument); } else { @@ -71,12 +70,13 @@ public class PayloadArgumentResolver implements RSocketServiceArgumentResolver { String message = "Async type for @Payload should produce value(s)"; Assert.isTrue(nestedParameter.getNestedParameterType() != Void.class, message); - Assert.isTrue(!reactiveAdapter.isNoValue(), message); + Assert.isTrue(!adapter.isNoValue(), message); requestValues.setPayload( - reactiveAdapter.toPublisher(argument), + adapter.toPublisher(argument), ParameterizedTypeReference.forType(nestedParameter.getNestedGenericParameterType())); } + return true; } } diff --git a/spring-web/src/main/java/org/springframework/web/service/invoker/HttpMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/service/invoker/HttpMethodArgumentResolver.java index 4a8cdd161e..0f0258045e 100644 --- a/spring-web/src/main/java/org/springframework/web/service/invoker/HttpMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/service/invoker/HttpMethodArgumentResolver.java @@ -63,6 +63,7 @@ public class HttpMethodArgumentResolver implements HttpServiceArgumentResolver { if (logger.isTraceEnabled()) { logger.trace("Resolved HTTP method to: " + httpMethod.name()); } + return true; } diff --git a/spring-web/src/main/java/org/springframework/web/service/invoker/RequestBodyArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/service/invoker/RequestBodyArgumentResolver.java index e35edb9171..a84ef532ac 100644 --- a/spring-web/src/main/java/org/springframework/web/service/invoker/RequestBodyArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/service/invoker/RequestBodyArgumentResolver.java @@ -81,8 +81,7 @@ public class RequestBodyArgumentResolver implements HttpServiceArgumentResolver } if (this.reactiveAdapterRegistry != null) { - ReactiveAdapter adapter = this.reactiveAdapterRegistry - .getAdapter(parameter.getParameterType()); + ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(parameter.getParameterType()); if (adapter != null) { MethodParameter nestedParameter = parameter.nested(); @@ -102,6 +101,7 @@ public class RequestBodyArgumentResolver implements HttpServiceArgumentResolver return true; } } + // Not a reactive type requestValues.setBodyValue(argument); return true;