Skip to content

Commit

Permalink
Minor refactoring in AbstractNamedValueArgumentResolver
Browse files Browse the repository at this point in the history
Expose MethodParameter information in abstract protected method that
adds the HTTP request value.

See gh-29420
  • Loading branch information
rstoyanchev committed Nov 2, 2022
1 parent 723e09c commit 4b647a1
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
Expand Down Expand Up @@ -83,10 +84,12 @@ public boolean resolve(

if (Map.class.isAssignableFrom(parameter.getParameterType())) {
Assert.isInstanceOf(Map.class, argument);
parameter = parameter.nested(1);
argument = (argument != null ? argument : Collections.emptyMap());
for (Map.Entry<String, ?> entry : ((Map<String, ?>) argument).entrySet()) {
addSingleOrMultipleValues(
entry.getKey(), entry.getValue(), false, null, info.label, info.multiValued,
null, requestValues);
parameter, requestValues);
}
}
else {
Expand Down Expand Up @@ -136,17 +139,20 @@ private NamedValueInfo updateNamedValueInfo(MethodParameter parameter, NamedValu

private void addSingleOrMultipleValues(
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) {

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) {
parameter = parameter.nested();
boolean hasValues = false;
for (Object element : elements) {
if (element != null) {
hasValues = true;
addSingleValue(name, element, false, null, valueLabel, null, requestValues);
addSingleValue(name, element, false, null, valueLabel, parameter, requestValues);
}
}
if (hasValues) {
Expand All @@ -160,8 +166,8 @@ private void addSingleOrMultipleValues(
}

private void addSingleValue(
String name, @Nullable Object value, boolean required, @Nullable Object defaultValue, String valueLabel,
@Nullable MethodParameter parameter, HttpRequestValues.Builder requestValues) {
String name, @Nullable Object value, boolean required, @Nullable Object defaultValue,
String valueLabel, MethodParameter parameter, HttpRequestValues.Builder requestValues) {

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

if (this.conversionService != null && !(value instanceof String)) {
parameter = (parameter != null ? parameter.nestedIfOptional() : null);
if (parameter != null && parameter.getNestedParameterType() != Object.class) {
value = this.conversionService.convert(value, new TypeDescriptor(parameter), STRING_TARGET_TYPE);
}
else {
value = this.conversionService.convert(value, String.class);
}
parameter = parameter.nestedIfOptional();
Class<?> type = parameter.getNestedParameterType();
value = (type != Object.class && !type.isArray() ?
this.conversionService.convert(value, new TypeDescriptor(parameter), STRING_TARGET_TYPE) :
this.conversionService.convert(value, String.class));
}

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

addRequestValue(name, value, requestValues);
addRequestValue(name, value, parameter, requestValues);
}

/**
Expand All @@ -200,9 +204,11 @@ private void addSingleValue(
* will have been converted to a String and may be cast down.
* @param name the request value name
* @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
*/
protected abstract void addRequestValue(String name, Object value, HttpRequestValues.Builder requestValues);
protected abstract void addRequestValue(
String name, Object value, MethodParameter parameter, HttpRequestValues.Builder requestValues);


/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
}

@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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
}

@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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
}

@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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
}

@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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
}

@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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@
import org.junit.jupiter.params.ParameterizedTest;
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.MediaType;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;

import static java.nio.charset.StandardCharsets.UTF_8;
Expand Down Expand Up @@ -106,4 +109,21 @@ void requestParamAsQueryParamsInUri() {
.isEqualTo("/path?param1=1st%20value&param2=2nd%20value%20A&param2=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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
}

@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);
}
}
Expand Down

0 comments on commit 4b647a1

Please sign in to comment.