Skip to content

Commit 4b647a1

Browse files
committed
Minor refactoring in AbstractNamedValueArgumentResolver
Expose MethodParameter information in abstract protected method that adds the HTTP request value. See gh-29420
1 parent 723e09c commit 4b647a1

File tree

8 files changed

+57
-21
lines changed

8 files changed

+57
-21
lines changed

spring-web/src/main/java/org/springframework/web/service/invoker/AbstractNamedValueArgumentResolver.java

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.Arrays;
2020
import java.util.Collection;
21+
import java.util.Collections;
2122
import java.util.Map;
2223
import java.util.Optional;
2324
import java.util.concurrent.ConcurrentHashMap;
@@ -83,10 +84,12 @@ public boolean resolve(
8384

8485
if (Map.class.isAssignableFrom(parameter.getParameterType())) {
8586
Assert.isInstanceOf(Map.class, argument);
87+
parameter = parameter.nested(1);
88+
argument = (argument != null ? argument : Collections.emptyMap());
8689
for (Map.Entry<String, ?> entry : ((Map<String, ?>) argument).entrySet()) {
8790
addSingleOrMultipleValues(
8891
entry.getKey(), entry.getValue(), false, null, info.label, info.multiValued,
89-
null, requestValues);
92+
parameter, requestValues);
9093
}
9194
}
9295
else {
@@ -136,17 +139,20 @@ private NamedValueInfo updateNamedValueInfo(MethodParameter parameter, NamedValu
136139

137140
private void addSingleOrMultipleValues(
138141
String name, @Nullable Object value, boolean required, @Nullable Object defaultValue,
139-
String valueLabel, boolean supportsMultiValues, @Nullable MethodParameter parameter,
142+
String valueLabel, boolean supportsMultiValues, MethodParameter parameter,
140143
HttpRequestValues.Builder requestValues) {
141144

142145
if (supportsMultiValues) {
143-
value = (ObjectUtils.isArray(value) ? Arrays.asList((Object[]) value) : value);
146+
if (ObjectUtils.isArray(value)) {
147+
value = Arrays.asList((Object[]) value);
148+
}
144149
if (value instanceof Collection<?> elements) {
150+
parameter = parameter.nested();
145151
boolean hasValues = false;
146152
for (Object element : elements) {
147153
if (element != null) {
148154
hasValues = true;
149-
addSingleValue(name, element, false, null, valueLabel, null, requestValues);
155+
addSingleValue(name, element, false, null, valueLabel, parameter, requestValues);
150156
}
151157
}
152158
if (hasValues) {
@@ -160,8 +166,8 @@ private void addSingleOrMultipleValues(
160166
}
161167

162168
private void addSingleValue(
163-
String name, @Nullable Object value, boolean required, @Nullable Object defaultValue, String valueLabel,
164-
@Nullable MethodParameter parameter, HttpRequestValues.Builder requestValues) {
169+
String name, @Nullable Object value, boolean required, @Nullable Object defaultValue,
170+
String valueLabel, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
165171

166172
if (value instanceof Optional<?> optionalValue) {
167173
value = optionalValue.orElse(null);
@@ -172,13 +178,11 @@ private void addSingleValue(
172178
}
173179

174180
if (this.conversionService != null && !(value instanceof String)) {
175-
parameter = (parameter != null ? parameter.nestedIfOptional() : null);
176-
if (parameter != null && parameter.getNestedParameterType() != Object.class) {
177-
value = this.conversionService.convert(value, new TypeDescriptor(parameter), STRING_TARGET_TYPE);
178-
}
179-
else {
180-
value = this.conversionService.convert(value, String.class);
181-
}
181+
parameter = parameter.nestedIfOptional();
182+
Class<?> type = parameter.getNestedParameterType();
183+
value = (type != Object.class && !type.isArray() ?
184+
this.conversionService.convert(value, new TypeDescriptor(parameter), STRING_TARGET_TYPE) :
185+
this.conversionService.convert(value, String.class));
182186
}
183187

184188
if (value == null) {
@@ -190,7 +194,7 @@ private void addSingleValue(
190194
logger.trace("Resolved " + valueLabel + " value '" + name + ":" + value + "'");
191195
}
192196

193-
addRequestValue(name, value, requestValues);
197+
addRequestValue(name, value, parameter, requestValues);
194198
}
195199

196200
/**
@@ -200,9 +204,11 @@ private void addSingleValue(
200204
* will have been converted to a String and may be cast down.
201205
* @param name the request value name
202206
* @param value the value
207+
* @param parameter the method parameter type, nested if Map, List/array, or Optional
203208
* @param requestValues builder to add the request value to
204209
*/
205-
protected abstract void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues);
210+
protected abstract void addRequestValue(
211+
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues);
206212

207213

208214
/**

spring-web/src/main/java/org/springframework/web/service/invoker/CookieValueArgumentResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
6363
}
6464

6565
@Override
66-
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
66+
protected void addRequestValue(
67+
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
68+
6769
requestValues.addCookie(name, (String) value);
6870
}
6971

spring-web/src/main/java/org/springframework/web/service/invoker/PathVariableArgumentResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
5555
}
5656

5757
@Override
58-
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
58+
protected void addRequestValue(
59+
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
60+
5961
requestValues.setUriVariable(name, (String) value);
6062
}
6163

spring-web/src/main/java/org/springframework/web/service/invoker/RequestAttributeArgumentResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
4747
}
4848

4949
@Override
50-
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
50+
protected void addRequestValue(
51+
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
52+
5153
requestValues.addAttribute(name, value);
5254
}
5355

spring-web/src/main/java/org/springframework/web/service/invoker/RequestHeaderArgumentResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
6464
}
6565

6666
@Override
67-
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
67+
protected void addRequestValue(
68+
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
69+
6870
requestValues.addHeader(name, (String) value);
6971
}
7072

spring-web/src/main/java/org/springframework/web/service/invoker/RequestParamArgumentResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
6767
}
6868

6969
@Override
70-
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
70+
protected void addRequestValue(
71+
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
72+
7173
requestValues.addRequestParameter(name, (String) value);
7274
}
7375

spring-web/src/test/java/org/springframework/web/service/invoker/HttpRequestValuesTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
import org.junit.jupiter.params.ParameterizedTest;
2323
import org.junit.jupiter.params.provider.ValueSource;
2424

25+
import org.springframework.http.HttpEntity;
26+
import org.springframework.http.HttpHeaders;
2527
import org.springframework.http.HttpMethod;
2628
import org.springframework.http.MediaType;
29+
import org.springframework.util.MultiValueMap;
2730
import org.springframework.web.util.UriComponentsBuilder;
2831

2932
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -106,4 +109,21 @@ void requestParamAsQueryParamsInUri() {
106109
.isEqualTo("/path?param1=1st%20value&param2=2nd%20value%20A&param2=2nd%20value%20B");
107110
}
108111

112+
@Test
113+
void requestPart() {
114+
HttpHeaders entityHeaders = new HttpHeaders();
115+
entityHeaders.add("foo", "bar");
116+
HttpEntity<String> entity = new HttpEntity<>("body", entityHeaders);
117+
118+
HttpRequestValues requestValues = HttpRequestValues.builder()
119+
.addRequestPart("form field", "form value")
120+
.addRequestPart("entity", entity)
121+
.build();
122+
123+
MultiValueMap<String, HttpEntity<?>> map = (MultiValueMap<String, HttpEntity<?>>) requestValues.getBodyValue();
124+
assertThat(map).hasSize(2);
125+
assertThat(map.getFirst("form field").getBody()).isEqualTo("form value");
126+
assertThat(map.getFirst("entity")).isEqualTo(entity);
127+
}
128+
109129
}

spring-web/src/test/java/org/springframework/web/service/invoker/NamedValueArgumentResolverTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
240240
}
241241

242242
@Override
243-
protected void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues) {
243+
protected void addRequestValue(String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues) {
244244
this.testValues.add(name, (String) value);
245245
}
246246
}

0 commit comments

Comments
 (0)