在这种情况下,@ModelAttribute
注释用于标识Spring应添加为模型属性的对象。模型属性是从属性抽象出来的。基本上,它们是由一些键标识的对象,这些键将进入属性。为此,可以手动添加带有 、的带注释方法的属性,或者使用 添加注释的方法参数。HttpServletRequest
HttpServletRequest
Model#addAttribute(String, Object)
@ModelAttribute
@ModelAttribute
您需要了解的是Spring如何解析处理程序方法参数并注入参数。它使用 HandlerMethodArgumentResolver
接口来执行此操作。有许多实现类(参见javadoc),每个类都有责任通过反射将Spring将使用的参数返回给你的处理程序方法。仅当该方法返回特定参数时,Spring 才会调用该方法。resolveArgument()
invoke()
resolveArgument()
HandlerMethodArgumentResolver
supportsParameter()
true
这里讨论的实现是ServletModelAttributeMethodProcessor
,它从ModelAttributeMethodProcessor
扩展而来,它指出HandlerMethodArgumentResolver
解析使用 @ModelAttribute 批注的方法参数,并处理使用 @ModelAttribute 批注的方法的返回值。
春天(3.2)将注册这个和其他HandlerMethodArgumentResolver
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
// Annotation-based argument resolution
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
resolvers.add(new RequestParamMapMethodArgumentResolver());
resolvers.add(new PathVariableMethodArgumentResolver());
resolvers.add(new ServletModelAttributeMethodProcessor(false));
resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters()));
resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters()));
resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
// Type-based argument resolution
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
resolvers.add(new HttpEntityMethodProcessor(getMessageConverters()));
resolvers.add(new RedirectAttributesMethodArgumentResolver());
resolvers.add(new ModelMethodProcessor());
resolvers.add(new MapMethodProcessor());
resolvers.add(new ErrorsMethodArgumentResolver());
resolvers.add(new SessionStatusMethodArgumentResolver());
resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
// Custom arguments
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
resolvers.add(new ServletModelAttributeMethodProcessor(true));
return resolvers;
}
当Spring需要调用您的处理程序方法时,它将循环访问参数类型和上面的列表,并使用第一个.supportsParameter()
请注意,添加了两个实例(一个在注释之后)。有一个字段,告诉它是否应该查找。第一个实例必须查找 ,第二个实例不查找。Spring这样做是为了让你注册自己的实例,请参阅注释。ServletModelAttributeMethodProcessor
//catch all
ModelAttributeMethodProcessor
annotationNotRequired
@ModelAttribute
@ModelAttribute
HandlerMethodArgumentResolver
// Custom arguments
具体说来
@RequestMapping(value = "/", method = RequestMethod.POST)
public String sayHello(Person person, Model model) {
model.addAttribute("person", person);
return "home";
}
在这种情况下,参数是否带注释并不重要。A将解析它并绑定表单字段,即。请求参数,到实例的字段。您甚至不需要将其添加到 中,因为该类将处理它。Person
ModelAttributeMethodProcessor
model
ModelAttributeMethodProcessor
在您的方法中showHelloPage()
model.addAttribute("person", new Person());
与 taglib 一起需要。这就是它解析其字段的方式。<form>
input
所以我的问题是 - “ModelAttribute”非自然化有什么用?
自动将指定的参数(或方法返回值)添加到模型中。
在表单中省略“modelAttribute”属性是否有某种方法?
否,绑定在 中查找对象并将其字段绑定到 html 元素。form
Model
input
第二部分,是什么方法(也许是一些注释)使表单自动将输入的值绑定到适当的bean属性(这将被声明为方法参数)?在发送表单之前无需添加空bean(因为我现在必须这样做)。
Spring 标记锁定到模型属性对象上,并使用其字段来创建和元素。无论对象最终如何出现在模型中,只要它确实如此,它就无关紧要。如果它找不到具有您指定的名称(键)的模型属性,它将引发异常,如您所见。<form>
input
label
<form:form method="post" modelAttribute="person">
提供空bean的替代方法是自己创建html。Spring所做的就是使用bean的字段名称来创建一个元素。所以这个<form>
input
<form:form method="post" modelAttribute="person">
<form:label path="firstName">First name</form:label>
<form:input path="firstName" />
创建类似的东西
<form method="post" action="[some action url]">
<label for="firstName">First name<label>
<input type="text" name="firstName" value="[whatever value firstName field had]" />
...
Spring 使用该属性将请求参数绑定到实例字段。name