Minor refactoring in AbstractNamedValueArgumentResolver
Expose MethodParameter information in abstract protected method that adds the HTTP request value. See gh-29420
This commit is contained in:
parent
723e09c164
commit
4b647a1801
|
|
@ -18,6 +18,7 @@ package org.springframework.web.service.invoker;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
@ -83,10 +84,12 @@ public abstract class AbstractNamedValueArgumentResolver implements HttpServiceA
|
||||||
|
|
||||||
if (Map.class.isAssignableFrom(parameter.getParameterType())) {
|
if (Map.class.isAssignableFrom(parameter.getParameterType())) {
|
||||||
Assert.isInstanceOf(Map.class, argument);
|
Assert.isInstanceOf(Map.class, argument);
|
||||||
|
parameter = parameter.nested(1);
|
||||||
|
argument = (argument != null ? argument : Collections.emptyMap());
|
||||||
for (Map.Entry<String, ?> entry : ((Map<String, ?>) argument).entrySet()) {
|
for (Map.Entry<String, ?> entry : ((Map<String, ?>) argument).entrySet()) {
|
||||||
addSingleOrMultipleValues(
|
addSingleOrMultipleValues(
|
||||||
entry.getKey(), entry.getValue(), false, null, info.label, info.multiValued,
|
entry.getKey(), entry.getValue(), false, null, info.label, info.multiValued,
|
||||||
null, requestValues);
|
parameter, requestValues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -136,17 +139,20 @@ public abstract class AbstractNamedValueArgumentResolver implements HttpServiceA
|
||||||
|
|
||||||
private void addSingleOrMultipleValues(
|
private void addSingleOrMultipleValues(
|
||||||
String name, @Nullable Object value, boolean required, @Nullable Object defaultValue,
|
String name, @Nullable Object value, boolean required, @Nullable Object defaultValue,
|
||||||
String valueLabel, boolean supportsMultiValues, @Nullable MethodParameter parameter,
|
String valueLabel, boolean supportsMultiValues, MethodParameter parameter,
|
||||||
HttpRequestValues.Builder requestValues) {
|
HttpRequestValues.Builder requestValues) {
|
||||||
|
|
||||||
if (supportsMultiValues) {
|
if (supportsMultiValues) {
|
||||||
value = (ObjectUtils.isArray(value) ? Arrays.asList((Object[]) value) : value);
|
if (ObjectUtils.isArray(value)) {
|
||||||
|
value = Arrays.asList((Object[]) value);
|
||||||
|
}
|
||||||
if (value instanceof Collection<?> elements) {
|
if (value instanceof Collection<?> elements) {
|
||||||
|
parameter = parameter.nested();
|
||||||
boolean hasValues = false;
|
boolean hasValues = false;
|
||||||
for (Object element : elements) {
|
for (Object element : elements) {
|
||||||
if (element != null) {
|
if (element != null) {
|
||||||
hasValues = true;
|
hasValues = true;
|
||||||
addSingleValue(name, element, false, null, valueLabel, null, requestValues);
|
addSingleValue(name, element, false, null, valueLabel, parameter, requestValues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasValues) {
|
if (hasValues) {
|
||||||
|
|
@ -160,8 +166,8 @@ public abstract class AbstractNamedValueArgumentResolver implements HttpServiceA
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSingleValue(
|
private void addSingleValue(
|
||||||
String name, @Nullable Object value, boolean required, @Nullable Object defaultValue, String valueLabel,
|
String name, @Nullable Object value, boolean required, @Nullable Object defaultValue,
|
||||||
@Nullable MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
String valueLabel, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||||
|
|
||||||
if (value instanceof Optional<?> optionalValue) {
|
if (value instanceof Optional<?> optionalValue) {
|
||||||
value = optionalValue.orElse(null);
|
value = optionalValue.orElse(null);
|
||||||
|
|
@ -172,13 +178,11 @@ public abstract class AbstractNamedValueArgumentResolver implements HttpServiceA
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.conversionService != null && !(value instanceof String)) {
|
if (this.conversionService != null && !(value instanceof String)) {
|
||||||
parameter = (parameter != null ? parameter.nestedIfOptional() : null);
|
parameter = parameter.nestedIfOptional();
|
||||||
if (parameter != null && parameter.getNestedParameterType() != Object.class) {
|
Class<?> type = parameter.getNestedParameterType();
|
||||||
value = this.conversionService.convert(value, new TypeDescriptor(parameter), STRING_TARGET_TYPE);
|
value = (type != Object.class && !type.isArray() ?
|
||||||
}
|
this.conversionService.convert(value, new TypeDescriptor(parameter), STRING_TARGET_TYPE) :
|
||||||
else {
|
this.conversionService.convert(value, String.class));
|
||||||
value = this.conversionService.convert(value, String.class);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
|
@ -190,7 +194,7 @@ public abstract class AbstractNamedValueArgumentResolver implements HttpServiceA
|
||||||
logger.trace("Resolved " + valueLabel + " value '" + name + ":" + value + "'");
|
logger.trace("Resolved " + valueLabel + " value '" + name + ":" + value + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
addRequestValue(name, value, requestValues);
|
addRequestValue(name, value, parameter, requestValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -200,9 +204,11 @@ public abstract class AbstractNamedValueArgumentResolver implements HttpServiceA
|
||||||
* will have been converted to a String and may be cast down.
|
* will have been converted to a String and may be cast down.
|
||||||
* @param name the request value name
|
* @param name the request value name
|
||||||
* @param value the value
|
* @param value the value
|
||||||
|
* @param parameter the method parameter type, nested if Map, List/array, or Optional
|
||||||
* @param requestValues builder to add the request value to
|
* @param requestValues builder to add the request value to
|
||||||
*/
|
*/
|
||||||
protected abstract void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues);
|
protected abstract void addRequestValue(
|
||||||
|
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,9 @@ public class CookieValueArgumentResolver extends AbstractNamedValueArgumentResol
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
|
protected void addRequestValue(
|
||||||
|
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||||
|
|
||||||
requestValues.addCookie(name, (String) value);
|
requestValues.addCookie(name, (String) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,9 @@ public class PathVariableArgumentResolver extends AbstractNamedValueArgumentReso
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
|
protected void addRequestValue(
|
||||||
|
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||||
|
|
||||||
requestValues.setUriVariable(name, (String) value);
|
requestValues.setUriVariable(name, (String) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,9 @@ public class RequestAttributeArgumentResolver extends AbstractNamedValueArgument
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
|
protected void addRequestValue(
|
||||||
|
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||||
|
|
||||||
requestValues.addAttribute(name, value);
|
requestValues.addAttribute(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,9 @@ public class RequestHeaderArgumentResolver extends AbstractNamedValueArgumentRes
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
|
protected void addRequestValue(
|
||||||
|
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||||
|
|
||||||
requestValues.addHeader(name, (String) value);
|
requestValues.addHeader(name, (String) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,9 @@ public class RequestParamArgumentResolver extends AbstractNamedValueArgumentReso
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
|
protected void addRequestValue(
|
||||||
|
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||||
|
|
||||||
requestValues.addRequestParameter(name, (String) value);
|
requestValues.addRequestParameter(name, (String) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,11 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
@ -106,4 +109,21 @@ public class HttpRequestValuesTests {
|
||||||
.isEqualTo("/path?param1=1st%20value¶m2=2nd%20value%20A¶m2=2nd%20value%20B");
|
.isEqualTo("/path?param1=1st%20value¶m2=2nd%20value%20A¶m2=2nd%20value%20B");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestPart() {
|
||||||
|
HttpHeaders entityHeaders = new HttpHeaders();
|
||||||
|
entityHeaders.add("foo", "bar");
|
||||||
|
HttpEntity<String> entity = new HttpEntity<>("body", entityHeaders);
|
||||||
|
|
||||||
|
HttpRequestValues requestValues = HttpRequestValues.builder()
|
||||||
|
.addRequestPart("form field", "form value")
|
||||||
|
.addRequestPart("entity", entity)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
MultiValueMap<String, HttpEntity<?>> map = (MultiValueMap<String, HttpEntity<?>>) requestValues.getBodyValue();
|
||||||
|
assertThat(map).hasSize(2);
|
||||||
|
assertThat(map.getFirst("form field").getBody()).isEqualTo("form value");
|
||||||
|
assertThat(map.getFirst("entity")).isEqualTo(entity);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,7 @@ class NamedValueArgumentResolverTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
|
protected void addRequestValue(String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
|
||||||
this.testValues.add(name, (String) value);
|
this.testValues.add(name, (String) value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue