|
|
|
@ -16,29 +16,37 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.web.servlet.mvc.method.annotation; |
|
|
|
package org.springframework.web.servlet.mvc.method.annotation; |
|
|
|
|
|
|
|
|
|
|
|
import static org.junit.Assert.*; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
import java.util.Optional; |
|
|
|
|
|
|
|
|
|
|
|
import org.junit.Before; |
|
|
|
import org.junit.Before; |
|
|
|
import org.junit.Test; |
|
|
|
import org.junit.Test; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.core.MethodParameter; |
|
|
|
import org.springframework.core.MethodParameter; |
|
|
|
|
|
|
|
import org.springframework.core.annotation.SynthesizingMethodParameter; |
|
|
|
|
|
|
|
import org.springframework.core.convert.support.DefaultConversionService; |
|
|
|
import org.springframework.mock.web.test.MockHttpServletRequest; |
|
|
|
import org.springframework.mock.web.test.MockHttpServletRequest; |
|
|
|
import org.springframework.mock.web.test.MockHttpServletResponse; |
|
|
|
import org.springframework.mock.web.test.MockHttpServletResponse; |
|
|
|
|
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
import org.springframework.web.bind.MissingPathVariableException; |
|
|
|
import org.springframework.web.bind.MissingPathVariableException; |
|
|
|
import org.springframework.web.bind.annotation.PathVariable; |
|
|
|
import org.springframework.web.bind.annotation.PathVariable; |
|
|
|
|
|
|
|
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; |
|
|
|
|
|
|
|
import org.springframework.web.bind.support.DefaultDataBinderFactory; |
|
|
|
|
|
|
|
import org.springframework.web.bind.support.WebDataBinderFactory; |
|
|
|
import org.springframework.web.context.request.ServletWebRequest; |
|
|
|
import org.springframework.web.context.request.ServletWebRequest; |
|
|
|
import org.springframework.web.method.support.ModelAndViewContainer; |
|
|
|
import org.springframework.web.method.support.ModelAndViewContainer; |
|
|
|
import org.springframework.web.servlet.HandlerMapping; |
|
|
|
import org.springframework.web.servlet.HandlerMapping; |
|
|
|
import org.springframework.web.servlet.View; |
|
|
|
import org.springframework.web.servlet.View; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static org.junit.Assert.*; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Test fixture with {@link PathVariableMethodArgumentResolver}. |
|
|
|
* Test fixture with {@link PathVariableMethodArgumentResolver}. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
|
|
|
|
* @author Juergen Hoeller |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class PathVariableMethodArgumentResolverTests { |
|
|
|
public class PathVariableMethodArgumentResolverTests { |
|
|
|
|
|
|
|
|
|
|
|
@ -48,25 +56,33 @@ public class PathVariableMethodArgumentResolverTests { |
|
|
|
|
|
|
|
|
|
|
|
private MethodParameter paramString; |
|
|
|
private MethodParameter paramString; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private MethodParameter paramNotRequired; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private MethodParameter paramOptional; |
|
|
|
|
|
|
|
|
|
|
|
private ModelAndViewContainer mavContainer; |
|
|
|
private ModelAndViewContainer mavContainer; |
|
|
|
|
|
|
|
|
|
|
|
private ServletWebRequest webRequest; |
|
|
|
private ServletWebRequest webRequest; |
|
|
|
|
|
|
|
|
|
|
|
private MockHttpServletRequest request; |
|
|
|
private MockHttpServletRequest request; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Before |
|
|
|
@Before |
|
|
|
public void setUp() throws Exception { |
|
|
|
public void setUp() throws Exception { |
|
|
|
resolver = new PathVariableMethodArgumentResolver(); |
|
|
|
resolver = new PathVariableMethodArgumentResolver(); |
|
|
|
|
|
|
|
|
|
|
|
Method method = getClass().getMethod("handle", String.class, String.class); |
|
|
|
Method method = ReflectionUtils.findMethod(getClass(), "handle", (Class<?>[]) null); |
|
|
|
paramNamedString = new MethodParameter(method, 0); |
|
|
|
paramNamedString = new SynthesizingMethodParameter(method, 0); |
|
|
|
paramString = new MethodParameter(method, 1); |
|
|
|
paramString = new SynthesizingMethodParameter(method, 1); |
|
|
|
|
|
|
|
paramNotRequired = new SynthesizingMethodParameter(method, 2); |
|
|
|
|
|
|
|
paramOptional = new SynthesizingMethodParameter(method, 3); |
|
|
|
|
|
|
|
|
|
|
|
mavContainer = new ModelAndViewContainer(); |
|
|
|
mavContainer = new ModelAndViewContainer(); |
|
|
|
request = new MockHttpServletRequest(); |
|
|
|
request = new MockHttpServletRequest(); |
|
|
|
webRequest = new ServletWebRequest(request, new MockHttpServletResponse()); |
|
|
|
webRequest = new ServletWebRequest(request, new MockHttpServletResponse()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void supportsParameter() { |
|
|
|
public void supportsParameter() { |
|
|
|
assertTrue("Parameter with @PathVariable annotation", resolver.supportsParameter(paramNamedString)); |
|
|
|
assertTrue("Parameter with @PathVariable annotation", resolver.supportsParameter(paramNamedString)); |
|
|
|
@ -89,21 +105,58 @@ public class PathVariableMethodArgumentResolverTests { |
|
|
|
assertEquals("value", pathVars.get("name")); |
|
|
|
assertEquals("value", pathVars.get("name")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
@Test |
|
|
|
|
|
|
|
public void resolveArgumentNotRequired() throws Exception { |
|
|
|
|
|
|
|
Map<String, String> uriTemplateVars = new HashMap<>(); |
|
|
|
|
|
|
|
uriTemplateVars.put("name", "value"); |
|
|
|
|
|
|
|
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String result = (String) resolver.resolveArgument(paramNotRequired, mavContainer, webRequest, null); |
|
|
|
|
|
|
|
assertEquals("PathVariable not resolved correctly", "value", result); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
|
|
Map<String, Object> pathVars = (Map<String, Object>) request.getAttribute(View.PATH_VARIABLES); |
|
|
|
|
|
|
|
assertNotNull(pathVars); |
|
|
|
|
|
|
|
assertEquals(1, pathVars.size()); |
|
|
|
|
|
|
|
assertEquals("value", pathVars.get("name")); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void resolveArgumentWrappedAsOptional() throws Exception { |
|
|
|
|
|
|
|
Map<String, String> uriTemplateVars = new HashMap<>(); |
|
|
|
|
|
|
|
uriTemplateVars.put("name", "value"); |
|
|
|
|
|
|
|
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); |
|
|
|
|
|
|
|
initializer.setConversionService(new DefaultConversionService()); |
|
|
|
|
|
|
|
WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
|
|
Optional<String> result = (Optional<String>) |
|
|
|
|
|
|
|
resolver.resolveArgument(paramOptional, mavContainer, webRequest, binderFactory); |
|
|
|
|
|
|
|
assertEquals("PathVariable not resolved correctly", "value", result.get()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
|
|
Map<String, Object> pathVars = (Map<String, Object>) request.getAttribute(View.PATH_VARIABLES); |
|
|
|
|
|
|
|
assertNotNull(pathVars); |
|
|
|
|
|
|
|
assertEquals(1, pathVars.size()); |
|
|
|
|
|
|
|
assertEquals(Optional.of("value"), pathVars.get("name")); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void resolveArgumentWithExistingPathVars() throws Exception { |
|
|
|
public void resolveArgumentWithExistingPathVars() throws Exception { |
|
|
|
Map<String, String> uriTemplateVars = new HashMap<>(); |
|
|
|
Map<String, String> uriTemplateVars = new HashMap<>(); |
|
|
|
uriTemplateVars.put("name", "value"); |
|
|
|
uriTemplateVars.put("name", "value"); |
|
|
|
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); |
|
|
|
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); |
|
|
|
|
|
|
|
|
|
|
|
Map<String, Object> pathVars; |
|
|
|
|
|
|
|
uriTemplateVars.put("oldName", "oldValue"); |
|
|
|
uriTemplateVars.put("oldName", "oldValue"); |
|
|
|
request.setAttribute(View.PATH_VARIABLES, uriTemplateVars); |
|
|
|
request.setAttribute(View.PATH_VARIABLES, uriTemplateVars); |
|
|
|
|
|
|
|
|
|
|
|
String result = (String) resolver.resolveArgument(paramNamedString, mavContainer, webRequest, null); |
|
|
|
String result = (String) resolver.resolveArgument(paramNamedString, mavContainer, webRequest, null); |
|
|
|
assertEquals("PathVariable not resolved correctly", "value", result); |
|
|
|
assertEquals("PathVariable not resolved correctly", "value", result); |
|
|
|
|
|
|
|
|
|
|
|
pathVars = (Map<String, Object>) request.getAttribute(View.PATH_VARIABLES); |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
|
|
Map<String, Object> pathVars = (Map<String, Object>) request.getAttribute(View.PATH_VARIABLES); |
|
|
|
assertNotNull(pathVars); |
|
|
|
assertNotNull(pathVars); |
|
|
|
assertEquals(2, pathVars.size()); |
|
|
|
assertEquals(2, pathVars.size()); |
|
|
|
assertEquals("value", pathVars.get("name")); |
|
|
|
assertEquals("value", pathVars.get("name")); |
|
|
|
@ -113,11 +166,28 @@ public class PathVariableMethodArgumentResolverTests { |
|
|
|
@Test(expected = MissingPathVariableException.class) |
|
|
|
@Test(expected = MissingPathVariableException.class) |
|
|
|
public void handleMissingValue() throws Exception { |
|
|
|
public void handleMissingValue() throws Exception { |
|
|
|
resolver.resolveArgument(paramNamedString, mavContainer, webRequest, null); |
|
|
|
resolver.resolveArgument(paramNamedString, mavContainer, webRequest, null); |
|
|
|
fail("Unresolved path variable should lead to exception."); |
|
|
|
fail("Unresolved path variable should lead to exception"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void nullIfNotRequired() throws Exception { |
|
|
|
|
|
|
|
assertNull(resolver.resolveArgument(paramNotRequired, mavContainer, webRequest, null)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void wrapEmptyWithOptional() throws Exception { |
|
|
|
|
|
|
|
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); |
|
|
|
|
|
|
|
initializer.setConversionService(new DefaultConversionService()); |
|
|
|
|
|
|
|
WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertEquals(Optional.empty(), resolver.resolveArgument(paramOptional, mavContainer, webRequest, binderFactory)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unused") |
|
|
|
@SuppressWarnings("unused") |
|
|
|
public void handle(@PathVariable(value = "name") String param1, String param2) { |
|
|
|
public void handle(@PathVariable("name") String param1, String param2, |
|
|
|
|
|
|
|
@PathVariable(name="name", required = false) String param3, |
|
|
|
|
|
|
|
@PathVariable("name") Optional<String> param4) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|