当前位置: 首页 > 知识库问答 >
问题:

Spring MVC 3中的表单提交-说明

陈寒
2023-03-14

我不理解Spring3 MVC中表单提交的工作原理。

我想做的,是创建一个控制器,它将使用用户的名字并显示给他。不知怎么的,我做了,但我真的不明白它是怎么工作的。所以..

<form:form method="post" modelAttribute="person">
    <form:label path="firstName">First name</form:label>
    <form:input path="firstName" />
    <br />

    <form:label path="lastName">Last name</form:label>
    <form:input path="lastName" />
    <br />

    <input type="submit" value="Submit" />
</form:form>

我还有一个控制器,看起来像这样:

@Controller
public class HomeController {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String showHelloPage(Model model) {
        model.addAttribute("person", new Person());
        return "home";
    }

    @RequestMapping(value = "/", method = RequestMethod.POST)
    public String sayHello(Person person, Model model) {
        model.addAttribute("person", person);
        return "home";
    }
}

为了向用户显示欢迎消息,我在JSP页面中使用以下代码:

<c:if test="${not empty person.firstName and not empty person.lastName}">
    Hello ${person.firstName} ${person.lastName}!
</c:if>

并且可以工作(我省略了XML配置文件,因为它们与问题无关)。

model.addAttribute("person", new Person());

从“showhellopage”方法中,我得到一个(常见的)异常“neuther BindingResult nor...”。

而且,在开始时,“sayhello”方法看起来像:

(...)
public String sayHello(@ModelAttribute("person") Person person, Model model) {
(...)

我的意思是,它有“modelAttribute”注释。我添加它,因为在我读过的教程中,它总是存在的。但在我移除它之后,一切都运行良好,就像以前一样。

共有1个答案

海雪松
2023-03-14

本例中的@modelattribute注释用于标识Spring应该添加为模型属性的对象。模型属性是对HttpServletRequest属性的抽象。基本上,它们是由某个键标识的对象,该键将找到进入HttpServletRequest属性的方式。您可以通过手动添加model#addattribute(String,Object)属性,使用@modelattribute注释方法,或者使用@modelattribute注释方法参数来实现此目的。

您需要理解的是Spring是如何解析处理程序方法参数和注入参数的。它使用HandlerMethodArgumentResolver接口执行此操作。有许多实现类(参见javadoc),每个类都有责任通过反射返回Spring将用于处理程序方法invoke()的参数来resolveargument()。只有在HandlerMethodArgumentResolverSupportsParameter()方法为特定参数返回True时,Spring才会调用ResolveArgument()方法。

这里讨论的HandlerMethodArgumentResolver实现是ServletModelAttributeMethodProcessor,它从ModelAttributeMethodProcessor扩展而来

解析用@ModelAttribute批注的方法参数,并处理用@ModelAttribute批注的方法的返回值。

Spring(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()的第一个。

注意,添加了ServletModelAttributeMethodProcessor的两个实例(一个在//Catch All注释之后)。ModelAttributeMethodProcessor有一个AnnotationNotreQuered字段,该字段告诉它是否应该查找@ModelAttribute。第一个实例必须查找@modelAttribute,第二个实例不查找。Spring这样做是为了可以注册自己的HandlerMethodArgumentResolver实例,请参阅//Custom Argument注释。

具体而言

@RequestMapping(value = "/", method = RequestMethod.POST)
public String sayHello(Person person, Model model) {
    model.addAttribute("person", person);
    return "home";
}

在这种情况下,您的person参数是否被注释并不重要。ModelAttributeMethodProcessor将解析它并绑定表单字段,即。请求参数设置到实例的字段。您甚至不需要将它添加到model中,因为ModelAttributeMethodProcessor类将处理它。

showHellopage()方法中

model.addAttribute("person", new Person());
标记库需要。这就是它解析 input字段的方式。

所以我的问题是--“modelAttribute”Anonnature有什么用?

若要自动将指定的参数(或方法返回值)添加到模型中,请执行以下操作。

在表单中省略一个“modelAttribute”属性是不是某种方法?

Spring标记锁定到模型属性对象上,并使用其字段创建inputlabel元素。对象最终如何进入模型并不重要,只要它进入了模型。如果它找不到具有您指定的名称(键)的模型属性,它会抛出异常,如您所见。

 <form:form method="post" modelAttribute="person">

提供空bean的替代方法是自己创建html。Spring的所做的只是使用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属性将请求参数绑定到实例字段。

 类似资料:
  • 问题内容: 我在理解Spring 3 MVC中的表单如何工作时遇到问题。 我想做的是创建一个控制器,该控制器将用户名显示给他。我以某种方式做到了,但我真的不了解它是如何工作的。所以.. 我有一个看起来像这样的表格: 我也有一个看起来像这样的控制器: 为了向用户显示欢迎消息,我在JSP页面中使用以下代码: 而且行得通(我忽略了XML配置文件,因为它们与问题无关)。 我认为表单中的“ modelAtt

  • 大家要切记这一点: 在任何 Single Page App中,js代码都不会产生 一个传统意义的form表单提交!(这会引起整个页面的刷新) 所以,我们往往用事件来实现.(桌面开发思维) 假设,我们在远程有个接口,可以接受别人的留言: URL: http://siwei.me/interface/blogs/add_comment 参数: content: 留言的内容. 请求方式: POST 返回

  • 获取Form变量 通过Action的如下方法可以获取变量: GetSlice GetString GetInt GetBool GetFloat GetFile GetForm 自动映射 通常我们通过http.Request.Form来获得从用户中请求到服务器端的数据,这些数据一般都是采用name,value的形式提交的。xweb默认支持自动将这些变量映射到Action的成员中,并且这种映射支持子

  • 问题内容: 我正在学习AngularJs的学习过程,发现几乎没有任何示例可用于现实世界。 我试图对如何使用最标准的组件提交表单并将其传递给PHP文件有一个清晰的了解。 我的小提琴。 有人在提交简单,无污染的表单方面有什么好的例子吗,这些表单会对我以及其他许多Angularjs初学者有所帮助。 当我说一个干净的表格时,我指的是这样的东西。 我的ng-app代码… 我猜我接下来要问的三个问题是… 我的

  • Framework7 可以通过ajax自动提交 有两种自动提交方式: 当用户提交了表单 (点击了提交按钮) 或者当通过代码触发了 "submit" 事件 当用户更改了表单的内容,或者当通过代码触发了 "change" 事件 submit时提交表单数据 只需要添加 "ajax-submit" class 在form上,当submit时就会自动通过ajax发送表单数据 <form action="se

  • 用户单击提交按钮或图像按钮时,就会提交表单。使用<input>或<button>都可以定义提交按钮,只要将其type 特性的值设置为"submit"即可,而图像按钮则是通过将<input>的type 特性值设置为"image"来定义的。因此,只要我们单击以下代码生成的按钮,就可以提交表单。 <!-- 通用提交按钮 --> <input type="submit" value="Submit For