The @ModelAttribute http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/web/bind/annotation/ModelAttribute.html在这种情况下,注释用于标识 Spring 应添加为模型属性的对象。模型属性是从HttpServletRequest
属性。基本上,它们是由某个键标识的对象,它们会找到进入HttpServletRequest
属性。您可以通过手动添加属性来完成此操作Model#addAttribute(String, Object)
, 有一个@ModelAttribute
带注释的方法,或者通过注释方法参数@ModelAttribute
.
您需要了解的是 Spring 如何解析处理程序方法参数并注入参数。它使用HandlerMethodArgumentResolver http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/web/method/support/HandlerMethodArgumentResolver.html%60接口来执行此操作。有许多实现类(参见 javadoc),每个类都有责任resolveArgument()
通过返回 Spring 将使用的参数invoke()
通过反射你的处理程序方法。 Spring只会调用resolveArgument()
方法如果HandlerMethodArgumentResolver
supportsParameter()
方法返回true
对于具体参数。
The HandlerMethodArgumentResolver
这里有问题的实施是ServletModelAttributeMethodProcessor http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/ServletModelAttributeMethodProcessor.html它延伸自ModelAttributeMethodProcessor http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.html其中指出
解析用 @ModelAttribute 注释的方法参数和句柄
从使用 @ModelAttribute 注释的方法返回值。
春天(3.2)将register http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.html this 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()
.
请注意,两个实例ServletModelAttributeMethodProcessor
添加(一个后一个//catch all
评论)。这ModelAttributeMethodProcessor
has a annotationNotRequired
字段告诉它是否应该寻找@ModelAttribute
或不。第一个实例必须寻找@ModelAttribute
,第二个没有。 Spring 这样做是为了让你可以注册你自己的HandlerMethodArgumentResolver
实例,请参阅// Custom arguments
评论。
具体来说
@RequestMapping(value = "/", method = RequestMethod.POST)
public String sayHello(Person person, Model model) {
model.addAttribute("person", person);
return "home";
}
在这种情况下,您是否Person
参数是否带注释。 AModelAttributeMethodProcessor
将解决它并绑定表单字段,即。请求参数,到实例的字段。您甚至不需要将其添加到model
as the ModelAttributeMethodProcessor
类会处理这个问题。
In your showHelloPage()
method
model.addAttribute("person", new Person());
需要与<form>
标签库。这就是它解决的方式input
fields.
所以我的问题是 - “ModelAttribute”有什么用
注释?
自动将指定的参数(或方法返回值)添加到模型中。
是否可以通过某种方式省略表单中的“modelAttribute”属性?
No, the form
绑定在中查找对象Model
并将其字段绑定到 htmlinput
元素。
第二部分,制作一个的方法是什么(也许是一些注释)
表单自动将输入的值绑定到正确的 bean 属性
(这将被声明为方法参数)?无需添加
在发送表单之前一个空bean(因为我现在必须这样做)。
一个春天<form>
标签锁定模型属性对象并使用其字段来创建input
and label
元素。对象如何最终出现在模型中并不重要,只要它存在即可。如果它找不到具有您指定的名称(键)的模型属性,则会抛出异常,如您所见。
<form:form method="post" modelAttribute="person">
提供空 bean 的替代方法是自己创建 html。都是春天的<form>
所做的就是使用 bean 的字段名称来创建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
属性。