@MatrixVariable resolvers for WebFlux
The information was already parsed and available in a request attribute but until now there were no argument resolvers to expose it. Issue: SPR-16005
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -26,17 +25,20 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.annotation.SynthesizingMethodParameter;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.annotation.MatrixVariable;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.ResolvableMethod;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.web.method.MvcAnnotationPredicates.matrixAttribute;
|
||||
|
||||
/**
|
||||
* Test fixture with {@link MatrixVariableMethodArgumentResolver}.
|
||||
@@ -53,11 +55,7 @@ public class MatrixVariablesMapMethodArgumentResolverTests {
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MethodParameter paramString;
|
||||
private MethodParameter paramMap;
|
||||
private MethodParameter paramMultivalueMap;
|
||||
private MethodParameter paramMapForPathVar;
|
||||
private MethodParameter paramMapWithName;
|
||||
private final ResolvableMethod testMethod = ResolvableMethod.on(this.getClass()).named("handle").build();
|
||||
|
||||
|
||||
@Before
|
||||
@@ -69,107 +67,126 @@ public class MatrixVariablesMapMethodArgumentResolverTests {
|
||||
|
||||
Map<String, MultiValueMap<String, String>> params = new LinkedHashMap<>();
|
||||
this.request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, params);
|
||||
|
||||
Method method = getClass().getMethod("handle", String.class,
|
||||
Map.class, MultiValueMap.class, MultiValueMap.class, Map.class);
|
||||
|
||||
this.paramString = new SynthesizingMethodParameter(method, 0);
|
||||
this.paramMap = new SynthesizingMethodParameter(method, 1);
|
||||
this.paramMultivalueMap = new SynthesizingMethodParameter(method, 2);
|
||||
this.paramMapForPathVar = new SynthesizingMethodParameter(method, 3);
|
||||
this.paramMapWithName = new SynthesizingMethodParameter(method, 4);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void supportsParameter() {
|
||||
assertFalse(resolver.supportsParameter(paramString));
|
||||
assertTrue(resolver.supportsParameter(paramMap));
|
||||
assertTrue(resolver.supportsParameter(paramMultivalueMap));
|
||||
assertTrue(resolver.supportsParameter(paramMapForPathVar));
|
||||
assertFalse(resolver.supportsParameter(paramMapWithName));
|
||||
|
||||
assertFalse(this.resolver.supportsParameter(this.testMethod.arg(String.class)));
|
||||
|
||||
assertTrue(this.resolver.supportsParameter(this.testMethod.annot(matrixAttribute().noName())
|
||||
.arg(Map.class, String.class, String.class)));
|
||||
|
||||
assertTrue(this.resolver.supportsParameter(this.testMethod.annot(matrixAttribute().noPathVar())
|
||||
.arg(MultiValueMap.class, String.class, String.class)));
|
||||
|
||||
assertTrue(this.resolver.supportsParameter(this.testMethod.annot(matrixAttribute().pathVar("cars"))
|
||||
.arg(MultiValueMap.class, String.class, String.class)));
|
||||
|
||||
assertFalse(this.resolver.supportsParameter(this.testMethod.annot(matrixAttribute().name("name"))
|
||||
.arg(Map.class, String.class, String.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgument() throws Exception {
|
||||
MultiValueMap<String, String> params = getMatrixVariables("cars");
|
||||
MultiValueMap<String, String> params = getVariablesFor("cars");
|
||||
params.add("colors", "red");
|
||||
params.add("colors", "green");
|
||||
params.add("colors", "blue");
|
||||
params.add("year", "2012");
|
||||
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().noName())
|
||||
.arg(Map.class, String.class, String.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> map = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMap, this.mavContainer, this.webRequest, null);
|
||||
Map<String, String> map = (Map<String, String>)
|
||||
this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals("red", map.get("colors"));
|
||||
|
||||
param = this.testMethod
|
||||
.annot(matrixAttribute().noPathVar())
|
||||
.arg(MultiValueMap.class, String.class, String.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
MultiValueMap<String, String> multivalueMap = (MultiValueMap<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMultivalueMap, this.mavContainer, this.webRequest, null);
|
||||
MultiValueMap<String, String> multivalueMap = (MultiValueMap<String, String>)
|
||||
this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Arrays.asList("red", "green", "blue"), multivalueMap.get("colors"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentPathVariable() throws Exception {
|
||||
MultiValueMap<String, String> params1 = getMatrixVariables("cars");
|
||||
MultiValueMap<String, String> params1 = getVariablesFor("cars");
|
||||
params1.add("colors", "red");
|
||||
params1.add("colors", "purple");
|
||||
|
||||
MultiValueMap<String, String> params2 = getMatrixVariables("planes");
|
||||
MultiValueMap<String, String> params2 = getVariablesFor("planes");
|
||||
params2.add("colors", "yellow");
|
||||
params2.add("colors", "orange");
|
||||
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().pathVar("cars"))
|
||||
.arg(MultiValueMap.class, String.class, String.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> mapForPathVar = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMapForPathVar, this.mavContainer, this.webRequest, null);
|
||||
param, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Arrays.asList("red", "purple"), mapForPathVar.get("colors"));
|
||||
|
||||
param = this.testMethod.annot(matrixAttribute().noName()).arg(Map.class, String.class, String.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> mapAll = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMap, this.mavContainer, this.webRequest, null);
|
||||
Map<String, String> mapAll = (Map<String, String>)
|
||||
this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals("red", mapAll.get("colors"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentNoParams() throws Exception {
|
||||
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().noName())
|
||||
.arg(Map.class, String.class, String.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> map = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMap, this.mavContainer, this.webRequest, null);
|
||||
Map<String, String> map = (Map<String, String>)
|
||||
this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Collections.emptyMap(), map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentNoMatch() throws Exception {
|
||||
MultiValueMap<String, String> params2 = getMatrixVariables("planes");
|
||||
MultiValueMap<String, String> params2 = getVariablesFor("planes");
|
||||
params2.add("colors", "yellow");
|
||||
params2.add("colors", "orange");
|
||||
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().pathVar("cars"))
|
||||
.arg(MultiValueMap.class, String.class, String.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> map = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMapForPathVar, this.mavContainer, this.webRequest, null);
|
||||
Map<String, String> map = (Map<String, String>)
|
||||
this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Collections.emptyMap(), map);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private MultiValueMap<String, String> getMatrixVariables(String pathVarName) {
|
||||
private MultiValueMap<String, String> getVariablesFor(String pathVarName) {
|
||||
Map<String, MultiValueMap<String, String>> matrixVariables =
|
||||
(Map<String, MultiValueMap<String, String>>) this.request.getAttribute(
|
||||
HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE);
|
||||
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
||||
matrixVariables.put(pathVarName, params);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handle(
|
||||
String stringArg,
|
||||
@MatrixVariable Map<String, String> map,
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -25,7 +24,6 @@ import java.util.Map;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
@@ -34,14 +32,17 @@ import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.ServletRequestBindingException;
|
||||
import org.springframework.web.bind.annotation.MatrixVariable;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.ResolvableMethod;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.web.method.MvcAnnotationPredicates.matrixAttribute;
|
||||
|
||||
/**
|
||||
* Test fixture with {@link MatrixVariableMethodArgumentResolver}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class MatrixVariablesMethodArgumentResolverTests {
|
||||
@@ -54,9 +55,7 @@ public class MatrixVariablesMethodArgumentResolverTests {
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MethodParameter paramString;
|
||||
private MethodParameter paramColors;
|
||||
private MethodParameter paramYear;
|
||||
private ResolvableMethod testMethod = ResolvableMethod.on(this.getClass()).named("handle").build();
|
||||
|
||||
|
||||
@Before
|
||||
@@ -68,77 +67,81 @@ public class MatrixVariablesMethodArgumentResolverTests {
|
||||
|
||||
Map<String, MultiValueMap<String, String>> params = new LinkedHashMap<>();
|
||||
this.request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, params);
|
||||
|
||||
Method method = getClass().getMethod("handle", String.class, List.class, int.class);
|
||||
this.paramString = new MethodParameter(method, 0);
|
||||
this.paramColors = new MethodParameter(method, 1);
|
||||
this.paramColors.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer());
|
||||
this.paramYear = new MethodParameter(method, 2);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void supportsParameter() {
|
||||
assertFalse(resolver.supportsParameter(paramString));
|
||||
assertTrue(resolver.supportsParameter(paramColors));
|
||||
assertTrue(resolver.supportsParameter(paramYear));
|
||||
|
||||
assertFalse(this.resolver.supportsParameter(this.testMethod.arg(String.class)));
|
||||
|
||||
assertTrue(this.resolver.supportsParameter(
|
||||
this.testMethod.annot(matrixAttribute().noName()).arg(List.class, String.class)));
|
||||
|
||||
assertTrue(this.resolver.supportsParameter(
|
||||
this.testMethod.annot(matrixAttribute().name("year")).arg(int.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgument() throws Exception {
|
||||
MultiValueMap<String, String> params = getMatrixVariables("cars");
|
||||
MultiValueMap<String, String> params = getVariablesFor("cars");
|
||||
params.add("colors", "red");
|
||||
params.add("colors", "green");
|
||||
params.add("colors", "blue");
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().noName()).arg(List.class, String.class);
|
||||
|
||||
assertEquals(Arrays.asList("red", "green", "blue"),
|
||||
this.resolver.resolveArgument(this.paramColors, this.mavContainer, this.webRequest, null));
|
||||
this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentPathVariable() throws Exception {
|
||||
getMatrixVariables("cars").add("year", "2006");
|
||||
getMatrixVariables("bikes").add("year", "2005");
|
||||
getVariablesFor("cars").add("year", "2006");
|
||||
getVariablesFor("bikes").add("year", "2005");
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().name("year")).arg(int.class);
|
||||
|
||||
assertEquals("2006", this.resolver.resolveArgument(this.paramYear, this.mavContainer, this.webRequest, null));
|
||||
assertEquals("2006", this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentDefaultValue() throws Exception {
|
||||
assertEquals("2013", resolver.resolveArgument(this.paramYear, this.mavContainer, this.webRequest, null));
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().name("year")).arg(int.class);
|
||||
assertEquals("2013", resolver.resolveArgument(param, this.mavContainer, this.webRequest, null));
|
||||
}
|
||||
|
||||
@Test(expected = ServletRequestBindingException.class)
|
||||
public void resolveArgumentMultipleMatches() throws Exception {
|
||||
getMatrixVariables("var1").add("colors", "red");
|
||||
getMatrixVariables("var2").add("colors", "green");
|
||||
getVariablesFor("var1").add("colors", "red");
|
||||
getVariablesFor("var2").add("colors", "green");
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().noName()).arg(List.class, String.class);
|
||||
|
||||
this.resolver.resolveArgument(this.paramColors, this.mavContainer, this.webRequest, null);
|
||||
this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null);
|
||||
}
|
||||
|
||||
@Test(expected = ServletRequestBindingException.class)
|
||||
public void resolveArgumentRequired() throws Exception {
|
||||
resolver.resolveArgument(this.paramColors, this.mavContainer, this.webRequest, null);
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().noName()).arg(List.class, String.class);
|
||||
this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentNoMatch() throws Exception {
|
||||
MultiValueMap<String, String> params = getMatrixVariables("cars");
|
||||
MultiValueMap<String, String> params = getVariablesFor("cars");
|
||||
params.add("anotherYear", "2012");
|
||||
MethodParameter param = this.testMethod.annot(matrixAttribute().name("year")).arg(int.class);
|
||||
|
||||
assertEquals("2013", this.resolver.resolveArgument(this.paramYear, this.mavContainer, this.webRequest, null));
|
||||
assertEquals("2013", this.resolver.resolveArgument(param, this.mavContainer, this.webRequest, null));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private MultiValueMap<String, String> getMatrixVariables(String pathVarName) {
|
||||
private MultiValueMap<String, String> getVariablesFor(String pathVarName) {
|
||||
Map<String, MultiValueMap<String, String>> matrixVariables =
|
||||
(Map<String, MultiValueMap<String, String>>) this.request.getAttribute(
|
||||
HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE);
|
||||
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
||||
matrixVariables.put(pathVarName, params);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user