parent
4ac4c1b868
commit
51de84e148
|
|
@ -978,6 +978,9 @@ method parameters:
|
|||
`MultiValueMap<String, ?>` 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`.
|
||||
|
||||
|===
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1115,7 +1115,8 @@ 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`
|
||||
`ReactiveAdapterRegistry`. The payload can't be null unless it's set as not required
|
||||
through the annotation, annotated with `@Nullable` or it is `Optional`.
|
||||
|
||||
| `Object`, if followed by `MimeType`
|
||||
| The value for a metadata entry in the input payload. This can be any `Object` as long
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
|
|
@ -29,6 +29,7 @@ import org.springframework.util.Assert;
|
|||
* annotated arguments.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 6.0
|
||||
*/
|
||||
public class PayloadArgumentResolver implements RSocketServiceArgumentResolver {
|
||||
|
|
@ -54,8 +55,14 @@ public class PayloadArgumentResolver implements RSocketServiceArgumentResolver {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (argument != null) {
|
||||
ReactiveAdapter reactiveAdapter = this.reactiveAdapterRegistry.getAdapter(parameter.getParameterType());
|
||||
if (argument == null) {
|
||||
boolean required = (annot == null || annot.required()) && !parameter.isOptional();
|
||||
Assert.isTrue(!required, () -> "Missing payload");
|
||||
return true;
|
||||
}
|
||||
|
||||
ReactiveAdapter reactiveAdapter = this.reactiveAdapterRegistry
|
||||
.getAdapter(parameter.getParameterType());
|
||||
if (reactiveAdapter == null) {
|
||||
requestValues.setPayloadValue(argument);
|
||||
}
|
||||
|
|
@ -70,9 +77,6 @@ public class PayloadArgumentResolver implements RSocketServiceArgumentResolver {
|
|||
reactiveAdapter.toPublisher(argument),
|
||||
ParameterizedTypeReference.forType(nestedParameter.getNestedGenericParameterType()));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import reactor.core.publisher.Mono;
|
|||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.ReactiveAdapterRegistry;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
|
@ -34,7 +35,9 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
|||
* Tests for {@link PayloadArgumentResolver}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
class PayloadArgumentResolverTests extends RSocketServiceArgumentResolverTestSupport {
|
||||
|
||||
@Override
|
||||
|
|
@ -47,9 +50,7 @@ class PayloadArgumentResolverTests extends RSocketServiceArgumentResolverTestSup
|
|||
String payload = "payloadValue";
|
||||
boolean resolved = execute(payload, initMethodParameter(Service.class, "execute", 0));
|
||||
|
||||
assertThat(resolved).isTrue();
|
||||
assertThat(getRequestValues().getPayloadValue()).isEqualTo(payload);
|
||||
assertThat(getRequestValues().getPayload()).isNull();
|
||||
assertPayload(resolved, payload);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -57,10 +58,7 @@ class PayloadArgumentResolverTests extends RSocketServiceArgumentResolverTestSup
|
|||
Mono<String> payloadMono = Mono.just("payloadValue");
|
||||
boolean resolved = execute(payloadMono, initMethodParameter(Service.class, "executeMono", 0));
|
||||
|
||||
assertThat(resolved).isTrue();
|
||||
assertThat(getRequestValues().getPayloadValue()).isNull();
|
||||
assertThat(getRequestValues().getPayload()).isSameAs(payloadMono);
|
||||
assertThat(getRequestValues().getPayloadElementType()).isEqualTo(new ParameterizedTypeReference<String>() {});
|
||||
assertPayloadMono(resolved, payloadMono);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -92,7 +90,7 @@ class PayloadArgumentResolverTests extends RSocketServiceArgumentResolverTestSup
|
|||
}
|
||||
|
||||
@Test
|
||||
void notRequestBody() {
|
||||
void notPayload() {
|
||||
MethodParameter parameter = initMethodParameter(Service.class, "executeNotAnnotated", 0);
|
||||
boolean resolved = execute("value", parameter);
|
||||
|
||||
|
|
@ -100,23 +98,69 @@ class PayloadArgumentResolverTests extends RSocketServiceArgumentResolverTestSup
|
|||
}
|
||||
|
||||
@Test
|
||||
void ignoreNull() {
|
||||
boolean resolved = execute(null, initMethodParameter(Service.class, "execute", 0));
|
||||
void nullPayload() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> execute(null, initMethodParameter(Service.class, "execute", 0)))
|
||||
.withMessage("Missing payload");
|
||||
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> execute(null, initMethodParameter(Service.class, "executeMono", 0)))
|
||||
.withMessage("Missing payload");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullPayloadWithNullable() {
|
||||
boolean resolved = execute(null, initMethodParameter(Service.class, "executeNullable", 0));
|
||||
assertNullValues(resolved);
|
||||
|
||||
boolean resolvedMono = execute(null, initMethodParameter(Service.class, "executeNullableMono", 0));
|
||||
assertNullValues(resolvedMono);
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullPayloadWithNotRequired() {
|
||||
boolean resolved = execute(null, initMethodParameter(Service.class, "executeNotRequired", 0));
|
||||
assertNullValues(resolved);
|
||||
|
||||
boolean resolvedMono = execute(null, initMethodParameter(Service.class, "executeNotRequiredMono", 0));
|
||||
assertNullValues(resolvedMono);
|
||||
}
|
||||
|
||||
private void assertPayload(boolean resolved, String payload) {
|
||||
assertThat(resolved).isTrue();
|
||||
assertThat(getRequestValues().getPayloadValue()).isEqualTo(payload);
|
||||
assertThat(getRequestValues().getPayload()).isNull();
|
||||
}
|
||||
|
||||
private void assertPayloadMono(boolean resolved, Mono<String> payloadMono) {
|
||||
assertThat(resolved).isTrue();
|
||||
assertThat(getRequestValues().getPayloadValue()).isNull();
|
||||
assertThat(getRequestValues().getPayload()).isSameAs(payloadMono);
|
||||
assertThat(getRequestValues().getPayloadElementType()).isEqualTo(new ParameterizedTypeReference<String>() { });
|
||||
}
|
||||
|
||||
private void assertNullValues(boolean resolved) {
|
||||
assertThat(resolved).isTrue();
|
||||
assertThat(getRequestValues().getPayloadValue()).isNull();
|
||||
assertThat(getRequestValues().getPayload()).isNull();
|
||||
assertThat(getRequestValues().getPayloadElementType()).isNull();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@SuppressWarnings({"unused"})
|
||||
private interface Service {
|
||||
|
||||
void execute(@Payload String body);
|
||||
|
||||
void executeNotRequired(@Payload(required = false) String body);
|
||||
|
||||
void executeNullable(@Nullable @Payload String body);
|
||||
|
||||
void executeMono(@Payload Mono<String> body);
|
||||
|
||||
void executeNullableMono(@Nullable @Payload Mono<String> body);
|
||||
|
||||
void executeNotRequiredMono(@Payload(required = false) Mono<String> body);
|
||||
|
||||
void executeSingle(@Payload Single<String> body);
|
||||
|
||||
void executeMonoVoid(@Payload Mono<Void> body);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import org.springframework.web.bind.annotation.ValueConstants;
|
|||
* request header, path variable, cookie, and others.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 6.0
|
||||
*/
|
||||
public abstract class AbstractNamedValueArgumentResolver implements HttpServiceArgumentResolver {
|
||||
|
|
@ -145,7 +146,7 @@ public abstract class AbstractNamedValueArgumentResolver implements HttpServiceA
|
|||
.formatted(parameter.getNestedParameterType().getName()));
|
||||
}
|
||||
}
|
||||
boolean required = (info.required && !parameter.getParameterType().equals(Optional.class));
|
||||
boolean required = (info.required && !parameter.isOptional());
|
||||
String defaultValue = (ValueConstants.DEFAULT_NONE.equals(info.defaultValue) ? null : info.defaultValue);
|
||||
return info.update(name, required, defaultValue);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.web.service.invoker;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
|
|
@ -41,17 +43,26 @@ public class HttpMethodArgumentResolver implements HttpServiceArgumentResolver {
|
|||
public boolean resolve(
|
||||
@Nullable Object argument, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||
|
||||
if (!parameter.getParameterType().equals(HttpMethod.class)) {
|
||||
parameter = parameter.nestedIfOptional();
|
||||
|
||||
if (!parameter.getNestedParameterType().equals(HttpMethod.class)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Assert.notNull(argument, "HttpMethod is required");
|
||||
if (argument instanceof Optional<?> optionalValue) {
|
||||
argument = optionalValue.orElse(null);
|
||||
}
|
||||
|
||||
if (argument == null) {
|
||||
Assert.isTrue(parameter.isOptional(), "HttpMethod is required");
|
||||
return true;
|
||||
}
|
||||
|
||||
HttpMethod httpMethod = (HttpMethod) argument;
|
||||
requestValues.setHttpMethod(httpMethod);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Resolved HTTP method to: " + httpMethod.name());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.web.service.invoker;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.ReactiveAdapter;
|
||||
|
|
@ -30,6 +32,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||
* annotated arguments.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 6.0
|
||||
*/
|
||||
public class RequestBodyArgumentResolver implements HttpServiceArgumentResolver {
|
||||
|
|
@ -68,9 +71,18 @@ public class RequestBodyArgumentResolver implements HttpServiceArgumentResolver
|
|||
return false;
|
||||
}
|
||||
|
||||
if (argument != null) {
|
||||
if (argument instanceof Optional<?> optionalValue) {
|
||||
argument = optionalValue.orElse(null);
|
||||
}
|
||||
|
||||
if (argument == null) {
|
||||
Assert.isTrue(!annot.required() || parameter.isOptional(), "RequestBody is required");
|
||||
return true;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
|
@ -90,11 +102,8 @@ public class RequestBodyArgumentResolver implements HttpServiceArgumentResolver
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Not a reactive type
|
||||
requestValues.setBodyValue(argument);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
|
|
@ -17,9 +17,11 @@
|
|||
package org.springframework.web.service.invoker;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.util.UriBuilderFactory;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
|
||||
|
|
@ -42,14 +44,22 @@ public class UriBuilderFactoryArgumentResolver implements HttpServiceArgumentRes
|
|||
public boolean resolve(
|
||||
@Nullable Object argument, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||
|
||||
if (!parameter.getParameterType().equals(UriBuilderFactory.class)) {
|
||||
parameter = parameter.nestedIfOptional();
|
||||
|
||||
if (!parameter.getNestedParameterType().equals(UriBuilderFactory.class)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (argument != null) {
|
||||
requestValues.setUriBuilderFactory((UriBuilderFactory) argument);
|
||||
if (argument instanceof Optional<?> optionalValue) {
|
||||
argument = optionalValue.orElse(null);
|
||||
}
|
||||
|
||||
if (argument == null) {
|
||||
Assert.isTrue(parameter.isOptional(), "UriBuilderFactory is required");
|
||||
return true;
|
||||
}
|
||||
|
||||
requestValues.setUriBuilderFactory((UriBuilderFactory) argument);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
|
|
@ -17,15 +17,18 @@
|
|||
package org.springframework.web.service.invoker;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link HttpServiceArgumentResolver} that resolves the URL for the request
|
||||
* from a {@link URI} argument.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 6.0
|
||||
*/
|
||||
public class UrlArgumentResolver implements HttpServiceArgumentResolver {
|
||||
|
|
@ -34,14 +37,22 @@ public class UrlArgumentResolver implements HttpServiceArgumentResolver {
|
|||
public boolean resolve(
|
||||
@Nullable Object argument, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||
|
||||
if (!parameter.getParameterType().equals(URI.class)) {
|
||||
parameter = parameter.nestedIfOptional();
|
||||
|
||||
if (!parameter.getNestedParameterType().equals(URI.class)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (argument != null) {
|
||||
requestValues.setUri((URI) argument);
|
||||
if (argument instanceof Optional<?> optionalValue) {
|
||||
argument = optionalValue.orElse(null);
|
||||
}
|
||||
|
||||
if (argument == null) {
|
||||
Assert.isTrue(parameter.isOptional(), "URI is required");
|
||||
return true;
|
||||
}
|
||||
|
||||
requestValues.setUri((URI) argument);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.web.service.invoker;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
|
@ -68,12 +70,38 @@ class HttpMethodArgumentResolverTests {
|
|||
assertThatIllegalArgumentException().isThrownBy(() -> this.service.execute(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullHttpMethodWithNullable() {
|
||||
this.service.executeNullableHttpMethod(null);
|
||||
assertThat(getActualMethod()).isEqualTo(HttpMethod.GET);
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullHttpMethodWithOptional() {
|
||||
this.service.executeOptionalHttpMethod(null);
|
||||
assertThat(getActualMethod()).isEqualTo(HttpMethod.GET);
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyOptionalHttpMethod() {
|
||||
this.service.executeOptionalHttpMethod(Optional.empty());
|
||||
assertThat(getActualMethod()).isEqualTo(HttpMethod.GET);
|
||||
}
|
||||
|
||||
@Test
|
||||
void optionalHttpMethod() {
|
||||
this.service.executeOptionalHttpMethod(Optional.of(HttpMethod.POST));
|
||||
assertThat(getActualMethod()).isEqualTo(HttpMethod.POST);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private HttpMethod getActualMethod() {
|
||||
return this.client.getRequestValues().getHttpMethod();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private interface Service {
|
||||
|
||||
@HttpExchange
|
||||
|
|
@ -85,6 +113,12 @@ class HttpMethodArgumentResolverTests {
|
|||
@GetExchange
|
||||
void executeNotHttpMethod(String test);
|
||||
|
||||
@GetExchange
|
||||
void executeNullableHttpMethod(@Nullable HttpMethod method);
|
||||
|
||||
@GetExchange
|
||||
void executeOptionalHttpMethod(Optional<HttpMethod> method);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
|||
* {@link TestValue @TestValue} annotation and {@link TestNamedValueArgumentResolver}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
class NamedValueArgumentResolverTests {
|
||||
|
||||
|
|
@ -134,7 +135,7 @@ class NamedValueArgumentResolverTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void optionalEmpthyWithDefaultValue() {
|
||||
void optionalEmptyWithDefaultValue() {
|
||||
this.service.executeOptionalWithDefaultValue(Optional.empty());
|
||||
assertTestValue("value", "default");
|
||||
}
|
||||
|
|
@ -157,6 +158,12 @@ class NamedValueArgumentResolverTests {
|
|||
assertTestValue("value", "test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullTestValueWithNullable() {
|
||||
this.service.executeNullable(null);
|
||||
assertTestValue("value");
|
||||
}
|
||||
|
||||
private void assertTestValue(String key, String... values) {
|
||||
List<String> actualValues = this.argumentResolver.getTestValues().get(key);
|
||||
if (ObjectUtils.isEmpty(values)) {
|
||||
|
|
@ -207,6 +214,9 @@ class NamedValueArgumentResolverTests {
|
|||
@GetExchange
|
||||
void executeMapWithOptionalValue(@TestValue Map<String, Optional<String>> values);
|
||||
|
||||
@GetExchange
|
||||
void executeNullable(@Nullable @TestValue String value);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.web.service.invoker;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import io.reactivex.rxjava3.core.Completable;
|
||||
import io.reactivex.rxjava3.core.Single;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -35,7 +37,9 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
|||
* Tests for {@link RequestBodyArgumentResolver}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
@SuppressWarnings({"DataFlowIssue", "OptionalAssignedToNull"})
|
||||
class RequestBodyArgumentResolverTests {
|
||||
|
||||
private final TestReactorExchangeAdapter client = new TestReactorExchangeAdapter();
|
||||
|
|
@ -102,18 +106,68 @@ class RequestBodyArgumentResolverTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void ignoreNull() {
|
||||
this.service.execute(null);
|
||||
void nullRequestBody() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.service.execute(null))
|
||||
.withMessage("RequestBody is required");
|
||||
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.service.executeMono(null))
|
||||
.withMessage("RequestBody is required");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullRequestBodyWithNullable() {
|
||||
this.service.executeNullable(null);
|
||||
|
||||
assertThat(getBodyValue()).isNull();
|
||||
assertThat(getPublisherBody()).isNull();
|
||||
|
||||
this.service.executeMono(null);
|
||||
this.service.executeNullableMono(null);
|
||||
|
||||
assertThat(getBodyValue()).isNull();
|
||||
assertThat(getPublisherBody()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullRequestBodyWithNotRequired() {
|
||||
this.service.executeNotRequired(null);
|
||||
|
||||
assertThat(getBodyValue()).isNull();
|
||||
assertThat(getPublisherBody()).isNull();
|
||||
|
||||
this.service.executeNotRequiredMono(null);
|
||||
|
||||
assertThat(getBodyValue()).isNull();
|
||||
assertThat(getPublisherBody()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullRequestBodyWithOptional() {
|
||||
this.service.executeOptional(null);
|
||||
|
||||
assertThat(getBodyValue()).isNull();
|
||||
assertThat(getPublisherBody()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyOptionalRequestBody() {
|
||||
this.service.executeOptional(Optional.empty());
|
||||
|
||||
assertThat(getBodyValue()).isNull();
|
||||
assertThat(getPublisherBody()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void optionalStringBody() {
|
||||
String body = "bodyValue";
|
||||
this.service.executeOptional(Optional.of(body));
|
||||
|
||||
assertThat(getBodyValue()).isEqualTo(body);
|
||||
assertThat(getPublisherBody()).isNull();
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private Object getBodyValue() {
|
||||
return getReactiveRequestValues().getBodyValue();
|
||||
|
|
@ -134,14 +188,30 @@ class RequestBodyArgumentResolverTests {
|
|||
}
|
||||
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private interface Service {
|
||||
|
||||
@GetExchange
|
||||
void execute(@RequestBody String body);
|
||||
|
||||
@GetExchange
|
||||
void executeNullable(@Nullable @RequestBody String body);
|
||||
|
||||
@GetExchange
|
||||
void executeNotRequired(@RequestBody(required = false) String body);
|
||||
|
||||
@GetExchange
|
||||
void executeOptional(@RequestBody Optional<String> body);
|
||||
|
||||
@GetExchange
|
||||
void executeMono(@RequestBody Mono<String> body);
|
||||
|
||||
@GetExchange
|
||||
void executeNullableMono(@Nullable @RequestBody Mono<String> body);
|
||||
|
||||
@GetExchange
|
||||
void executeNotRequiredMono(@RequestBody(required = false) Mono<String> body);
|
||||
|
||||
@GetExchange
|
||||
void executeSingle(@RequestBody Single<String> body);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.web.service.invoker;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
|
@ -24,12 +26,14 @@ import org.springframework.web.util.DefaultUriBuilderFactory;
|
|||
import org.springframework.web.util.UriBuilderFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link UriBuilderFactoryArgumentResolver}.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
@SuppressWarnings({"DataFlowIssue", "OptionalAssignedToNull"})
|
||||
class UriBuilderFactoryArgumentResolverTests {
|
||||
|
||||
private final TestExchangeAdapter client = new TestExchangeAdapter();
|
||||
|
|
@ -49,24 +53,65 @@ class UriBuilderFactoryArgumentResolverTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void ignoreNullUriBuilderFactory(){
|
||||
this.service.execute(null);
|
||||
void nullUriBuilderFactory() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.service.execute(null))
|
||||
.withMessage("UriBuilderFactory is required");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullUriBuilderFactoryWithNullable(){
|
||||
this.service.executeNullable(null);
|
||||
|
||||
assertThat(getRequestValues().getUriBuilderFactory()).isEqualTo(null);
|
||||
assertThat(getRequestValues().getUriTemplate()).isEqualTo("/path");
|
||||
assertThat(getRequestValues().getUri()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullUriBuilderFactoryWithOptional(){
|
||||
this.service.executeOptional(null);
|
||||
|
||||
assertThat(getRequestValues().getUriBuilderFactory()).isEqualTo(null);
|
||||
assertThat(getRequestValues().getUriTemplate()).isEqualTo("/path");
|
||||
assertThat(getRequestValues().getUri()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyOptionalUriBuilderFactory(){
|
||||
this.service.executeOptional(Optional.empty());
|
||||
|
||||
assertThat(getRequestValues().getUriBuilderFactory()).isEqualTo(null);
|
||||
assertThat(getRequestValues().getUriTemplate()).isEqualTo("/path");
|
||||
assertThat(getRequestValues().getUri()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void optionalUriBuilderFactory(){
|
||||
UriBuilderFactory factory = new DefaultUriBuilderFactory("https://example.com");
|
||||
this.service.executeOptional(Optional.of(factory));
|
||||
|
||||
assertThat(getRequestValues().getUriBuilderFactory()).isEqualTo(factory);
|
||||
assertThat(getRequestValues().getUriTemplate()).isEqualTo("/path");
|
||||
assertThat(getRequestValues().getUri()).isNull();
|
||||
}
|
||||
|
||||
private HttpRequestValues getRequestValues() {
|
||||
return this.client.getRequestValues();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private interface Service {
|
||||
|
||||
@GetExchange("/path")
|
||||
void execute(@Nullable UriBuilderFactory uri);
|
||||
void execute(UriBuilderFactory uri);
|
||||
|
||||
@GetExchange("/path")
|
||||
void executeNullable(@Nullable UriBuilderFactory uri);
|
||||
|
||||
@GetExchange("/path")
|
||||
void executeOptional(Optional<UriBuilderFactory> uri);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.web.service.invoker;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -24,13 +25,16 @@ import org.springframework.lang.Nullable;
|
|||
import org.springframework.web.service.annotation.GetExchange;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link UrlArgumentResolver}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
@SuppressWarnings({"DataFlowIssue", "OptionalAssignedToNull"})
|
||||
class UrlArgumentResolverTests {
|
||||
|
||||
private final TestExchangeAdapter client = new TestExchangeAdapter();
|
||||
|
|
@ -59,22 +63,62 @@ class UrlArgumentResolverTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void ignoreNull() {
|
||||
this.service.execute(null);
|
||||
void nullUrl() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.service.execute(null))
|
||||
.withMessage("URI is required");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullUrlWithNullable() {
|
||||
this.service.executeNullable(null);
|
||||
|
||||
assertThat(getRequestValues().getUri()).isNull();
|
||||
assertThat(getRequestValues().getUriTemplate()).isEqualTo("/path");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullUrlWithOptional() {
|
||||
this.service.executeOptional(null);
|
||||
|
||||
assertThat(getRequestValues().getUri()).isNull();
|
||||
assertThat(getRequestValues().getUriTemplate()).isEqualTo("/path");
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyOptionalUrl() {
|
||||
this.service.executeOptional(Optional.empty());
|
||||
|
||||
assertThat(getRequestValues().getUri()).isNull();
|
||||
assertThat(getRequestValues().getUriTemplate()).isEqualTo("/path");
|
||||
}
|
||||
|
||||
@Test
|
||||
void optionalUrl() {
|
||||
URI dynamicUrl = URI.create("dynamic-path");
|
||||
this.service.executeOptional(Optional.of(dynamicUrl));
|
||||
|
||||
assertThat(getRequestValues().getUri()).isEqualTo(dynamicUrl);
|
||||
assertThat(getRequestValues().getUriTemplate()).isEqualTo("/path");
|
||||
}
|
||||
|
||||
|
||||
private HttpRequestValues getRequestValues() {
|
||||
return this.client.getRequestValues();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private interface Service {
|
||||
|
||||
@GetExchange("/path")
|
||||
void execute(@Nullable URI uri);
|
||||
void execute(URI uri);
|
||||
|
||||
@GetExchange("/path")
|
||||
void executeNullable(@Nullable URI uri);
|
||||
|
||||
@GetExchange("/path")
|
||||
void executeOptional(Optional<URI> uri);
|
||||
|
||||
@GetExchange
|
||||
void executeNotUri(String other);
|
||||
|
|
|
|||
Loading…
Reference in New Issue