SPR-7543 Add @PathVariables to the model
This commit is contained in:
parent
a4716c2a94
commit
ed9d9a402b
|
|
@ -27,6 +27,7 @@ import org.springframework.web.bind.annotation.ValueConstants;
|
|||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.method.annotation.support.AbstractNamedValueMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
/**
|
||||
|
|
@ -73,6 +74,17 @@ public class PathVariableMethodArgumentResolver extends AbstractNamedValueMethod
|
|||
throw new IllegalStateException("Could not find the URL template variable [" + name + "]");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleResolvedValue(Object arg,
|
||||
String name,
|
||||
MethodParameter parameter,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest) {
|
||||
if (mavContainer != null) {
|
||||
mavContainer.addAttribute(name, arg);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PathVariableNamedValueInfo extends NamedValueInfo {
|
||||
|
||||
private PathVariableNamedValueInfo(PathVariable annotation) {
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
|
|||
@ModelAttribute OtherUser otherUser,
|
||||
Model model) throws Exception {
|
||||
|
||||
model.addAttribute("cookie", cookie).addAttribute("pathvar", pathvar).addAttribute("header", header)
|
||||
model.addAttribute("cookie", cookie).addAttribute("header", header)
|
||||
.addAttribute("systemHeader", systemHeader).addAttribute("headerMap", headerMap)
|
||||
.addAttribute("dateParam", dateParam).addAttribute("paramMap", paramMap)
|
||||
.addAttribute("paramByConvention", paramByConvention).addAttribute("value", value)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
|
|||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.PathVariableMethodArgumentResolver;
|
||||
|
||||
|
|
@ -48,6 +49,8 @@ public class PathVariableMethodArgumentResolverTests {
|
|||
|
||||
private MethodParameter paramString;
|
||||
|
||||
private ModelAndViewContainer mavContainer;
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
|
@ -60,6 +63,7 @@ public class PathVariableMethodArgumentResolverTests {
|
|||
paramNamedString = new MethodParameter(method, 0);
|
||||
paramString = new MethodParameter(method, 1);
|
||||
|
||||
mavContainer = new ModelAndViewContainer();
|
||||
request = new MockHttpServletRequest();
|
||||
webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
|
||||
}
|
||||
|
|
@ -76,13 +80,14 @@ public class PathVariableMethodArgumentResolverTests {
|
|||
uriTemplateVars.put("name", "value");
|
||||
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
|
||||
|
||||
String result = (String) resolver.resolveArgument(paramNamedString, null, webRequest, null);
|
||||
assertEquals("value", result);
|
||||
String result = (String) resolver.resolveArgument(paramNamedString, mavContainer, webRequest, null);
|
||||
assertEquals("PathVariable not resolved correctly", "value", result);
|
||||
assertEquals("PathVariable not added to the model", "value", mavContainer.getAttribute("name"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void handleMissingValue() throws Exception {
|
||||
resolver.resolveArgument(paramNamedString, null, webRequest, null);
|
||||
resolver.resolveArgument(paramNamedString, mavContainer, webRequest, null);
|
||||
fail("Unresolved path variable should lead to exception.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
|||
* <li>Obtain named value information for a method parameter
|
||||
* <li>Resolve names into argument values
|
||||
* <li>Handle missing argument values when argument values are required
|
||||
* <li>Optionally handle a resolved value
|
||||
* </ul>
|
||||
* <p>A default value string can contain ${...} placeholders and Spring Expression Language #{...} expressions.
|
||||
* For this to work a {@link ConfigurableBeanFactory} must be supplied to the class constructor.
|
||||
|
|
@ -87,17 +88,18 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
|||
else if (namedValueInfo.required) {
|
||||
handleMissingValue(namedValueInfo.name, parameter);
|
||||
}
|
||||
arg = checkForNull(namedValueInfo.name, arg, paramType);
|
||||
arg = handleNullValue(namedValueInfo.name, arg, paramType);
|
||||
}
|
||||
|
||||
if (binderFactory != null) {
|
||||
WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);
|
||||
return binder.convertIfNecessary(arg, paramType, parameter);
|
||||
arg = binder.convertIfNecessary(arg, paramType, parameter);
|
||||
}
|
||||
else {
|
||||
|
||||
handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);
|
||||
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the named value for the given method parameter.
|
||||
|
|
@ -170,7 +172,10 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
|||
*/
|
||||
protected abstract void handleMissingValue(String name, MethodParameter parameter) throws ServletException;
|
||||
|
||||
private Object checkForNull(String name, Object value, Class<?> paramType) {
|
||||
/**
|
||||
* A {@code null} results in a {@code false} value for {@code boolean}s or an exception for other primitives.
|
||||
*/
|
||||
private Object handleNullValue(String name, Object value, Class<?> paramType) {
|
||||
if (value == null) {
|
||||
if (Boolean.TYPE.equals(paramType)) {
|
||||
return Boolean.FALSE;
|
||||
|
|
@ -184,6 +189,19 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked after a value is resolved.
|
||||
* @param arg the resolved argument value
|
||||
* @param name the argument name
|
||||
* @param parameter the argument parameter type
|
||||
* @param mavContainer the {@link ModelAndViewContainer}, which may be {@code null}
|
||||
* @param webRequest the current request
|
||||
*/
|
||||
protected void handleResolvedValue(Object arg, String name, MethodParameter parameter,
|
||||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the information about a named value, including name, whether it's required and a default value.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue