request handler methods with @ModelAttribute annotation always return a model attribute (SPR-4867)
This commit is contained in:
@@ -136,10 +136,10 @@ public class HandlerMethodInvoker {
|
||||
Object attrValue = doInvokeMethod(attributeMethodToInvoke, handler, args);
|
||||
String attrName = AnnotationUtils.findAnnotation(attributeMethodToInvoke, ModelAttribute.class).value();
|
||||
if ("".equals(attrName)) {
|
||||
Class resolvedType =
|
||||
GenericTypeResolver.resolveReturnType(attributeMethodToInvoke, handler.getClass());
|
||||
attrName =
|
||||
Conventions.getVariableNameForReturnType(attributeMethodToInvoke, resolvedType, attrValue);
|
||||
Class resolvedType = GenericTypeResolver.resolveReturnType(
|
||||
attributeMethodToInvoke, handler.getClass());
|
||||
attrName = Conventions.getVariableNameForReturnType(
|
||||
attributeMethodToInvoke, resolvedType, attrValue);
|
||||
}
|
||||
implicitModel.addAttribute(attrName, attrValue);
|
||||
}
|
||||
@@ -156,10 +156,8 @@ public class HandlerMethodInvoker {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object[] resolveHandlerArguments(Method handlerMethod,
|
||||
Object handler,
|
||||
NativeWebRequest webRequest,
|
||||
ExtendedModelMap implicitModel) throws Exception {
|
||||
private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,
|
||||
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
|
||||
|
||||
Class[] paramTypes = handlerMethod.getParameterTypes();
|
||||
Object[] args = new Object[paramTypes.length];
|
||||
@@ -446,7 +444,6 @@ public class HandlerMethodInvoker {
|
||||
throws Exception {
|
||||
|
||||
HttpInputMessage inputMessage = createHttpInputMessage(webRequest);
|
||||
|
||||
Class paramType = methodParam.getParameterType();
|
||||
MediaType contentType = inputMessage.getHeaders().getContentType();
|
||||
if (contentType == null) {
|
||||
@@ -463,16 +460,14 @@ public class HandlerMethodInvoker {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link HttpInputMessage} for the given {@link NativeWebRequest}.
|
||||
* Return a {@link HttpInputMessage} for the given {@link NativeWebRequest}.
|
||||
* Throws an UnsupportedOperationException by default.
|
||||
*/
|
||||
protected HttpInputMessage createHttpInputMessage(NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
throw new UnsupportedOperationException("@RequestBody not supported");
|
||||
}
|
||||
|
||||
@@ -585,10 +580,8 @@ public class HandlerMethodInvoker {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void updateModelAttributes(Object handler,
|
||||
Map mavModel,
|
||||
ExtendedModelMap implicitModel,
|
||||
NativeWebRequest webRequest) throws Exception {
|
||||
public final void updateModelAttributes(Object handler, Map<String, Object> mavModel,
|
||||
ExtendedModelMap implicitModel, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
if (this.methodResolver.hasSessionAttributes() && this.sessionStatus.isComplete()) {
|
||||
for (String attrName : this.methodResolver.getActualSessionAttributeNames()) {
|
||||
@@ -692,11 +685,22 @@ public class HandlerMethodInvoker {
|
||||
}
|
||||
|
||||
protected Object resolveStandardArgument(Class parameterType, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
if (WebRequest.class.isAssignableFrom(parameterType)) {
|
||||
return webRequest;
|
||||
}
|
||||
return WebArgumentResolver.UNRESOLVED;
|
||||
}
|
||||
|
||||
protected final void addReturnValueAsModelAttribute(
|
||||
Method handlerMethod, Class handlerType, Object returnValue, ExtendedModelMap implicitModel) {
|
||||
|
||||
ModelAttribute attr = AnnotationUtils.findAnnotation(handlerMethod, ModelAttribute.class);
|
||||
String attrName = (attr != null ? attr.value() : "");
|
||||
if ("".equals(attrName)) {
|
||||
Class resolvedType = GenericTypeResolver.resolveReturnType(handlerMethod, handlerType);
|
||||
attrName = Conventions.getVariableNameForReturnType(handlerMethod, resolvedType, returnValue);
|
||||
}
|
||||
implicitModel.addAttribute(attrName, returnValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,8 +45,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
@@ -662,12 +660,16 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
|
||||
else if (returnValue instanceof Model) {
|
||||
return new ModelAndView().addAllObjects(implicitModel).addAllObjects(((Model) returnValue).asMap());
|
||||
}
|
||||
else if (returnValue instanceof Map) {
|
||||
return new ModelAndView().addAllObjects(implicitModel).addAllObjects((Map) returnValue);
|
||||
}
|
||||
else if (returnValue instanceof View) {
|
||||
return new ModelAndView((View) returnValue).addAllObjects(implicitModel);
|
||||
}
|
||||
else if (handlerMethod.isAnnotationPresent(ModelAttribute.class)) {
|
||||
addReturnValueAsModelAttribute(handlerMethod, handlerType, returnValue, implicitModel);
|
||||
return new ModelAndView().addAllObjects(implicitModel);
|
||||
}
|
||||
else if (returnValue instanceof Map) {
|
||||
return new ModelAndView().addAllObjects(implicitModel).addAllObjects((Map) returnValue);
|
||||
}
|
||||
else if (returnValue instanceof String) {
|
||||
return new ModelAndView((String) returnValue).addAllObjects(implicitModel);
|
||||
}
|
||||
@@ -683,14 +685,8 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
|
||||
}
|
||||
else if (!BeanUtils.isSimpleProperty(returnValue.getClass())) {
|
||||
// Assume a single model attribute...
|
||||
ModelAttribute attr = AnnotationUtils.findAnnotation(handlerMethod, ModelAttribute.class);
|
||||
String attrName = (attr != null ? attr.value() : "");
|
||||
ModelAndView mav = new ModelAndView().addAllObjects(implicitModel);
|
||||
if ("".equals(attrName)) {
|
||||
Class resolvedType = GenericTypeResolver.resolveReturnType(handlerMethod, handlerType);
|
||||
attrName = Conventions.getVariableNameForReturnType(handlerMethod, resolvedType, returnValue);
|
||||
}
|
||||
return mav.addObject(attrName, returnValue);
|
||||
addReturnValueAsModelAttribute(handlerMethod, handlerType, returnValue, implicitModel);
|
||||
return new ModelAndView().addAllObjects(implicitModel);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid handler method return value: " + returnValue);
|
||||
@@ -726,6 +722,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Comparator capable of sorting {@link RequestMappingInfo}s (RHIs) so that sorting a list with this comparator will
|
||||
* result in: <ul> <li>RHIs with {@linkplain RequestMappingInfo#matchedPaths better matched paths} take prescedence
|
||||
|
||||
Reference in New Issue
Block a user