Contents

Spring MVC的表单入门

1.概述

在本文中,我们将讨论 Spring 表单和与控制器的数据绑定。此外,我们将看看Spring MVC中的主要注释之一,即*@ModelAttribute*。

2. Model

首先——让我们定义一个简单的实体,我们将显示并绑定到表单:

public class Employee {
    private String name;
    private long id;
    private String contactNumber;
    // standard getters and setters
}

这将是我们的表单支持对象。

3. View

接下来——让我们定义实际的表单,当然还有包含它的 HTML 文件。我们将使用一个创建/注册新员工的页面:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
    <head>
    </head>
    <body>
        <h3>Welcome, Enter The Employee Details</h3>
        <form:form method="POST" 
          action="/spring-mvc-xml/addEmployee" modelAttribute="employee">
             <table>
                <tr>
                    <td><form:label path="name">Name</form:label></td>
                    <td><form:input path="name"/></td>
                </tr>
                <tr>
                    <td><form:label path="id">Id</form:label></td>
                    <td><form:input path="id"/></td>
                </tr>
                <tr>
                    <td><form:label path="contactNumber">
                      Contact Number</form:label></td>
                    <td><form:input path="contactNumber"/></td>
                </tr>
                <tr>
                    <td><input type="submit" value="Submit"/></td>
                </tr>
            </table>
        </form:form>
    </body>
</html>

首先——请注意,我们在 JSP 页面中包含了一个标签库——form标签库——以帮助定义我们的表单。 Next – form:form 标签在这里扮演着重要的角色;它与常规的 HTLM <form>标记非常相似,但modelAttribute属性是指定支持此表单的模型对象名称的键:

<form:form method="POST" 
  action="/SpringMVCFormExample/addEmployee" modelAttribute="employee">

这将对应于稍后在控制器中的*@ModelAttribute* 。

接下来 – 每个输入字段都使用 Spring Form taglib 中的另一个有用标签 – form: prefix。这些字段中的每一个都指定了一个路径属性——这必须对应于模型属性的 getter/setter(在本例中为 Employee 类)。加载页面时,输入字段由 Spring 填充,它调用绑定到输入字段的每个字段的 getter。提交表单时,会调用 setter 将表单的值保存到对象中。

最后——当表单提交时,控制器中的 POST 处理程序被调用,表单自动绑定到我们传入的*employee *参数。

4. Controller

现在,让我们看看将处理后端的 Controller :

@Controller
public class EmployeeController {
    @RequestMapping(value = "/employee", method = RequestMethod.GET)
    public ModelAndView showForm() {
        return new ModelAndView("employeeHome", "employee", new Employee());
    }
    @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
    public String submit(@Valid @ModelAttribute("employee")Employee employee, 
      BindingResult result, ModelMap model) {
        if (result.hasErrors()) {
            return "error";
        }
        model.addAttribute("name", employee.getName());
        model.addAttribute("contactNumber", employee.getContactNumber());
        model.addAttribute("id", employee.getId());
        return "employeeView";
    }
}

控制器定义了两个简单的操作——GET 用于在表单中显示数据,POST 用于创建操作,通过表单的提交。

还要注意,如果没有将名为“employee”的对象添加到模型中,当我们尝试访问 JSP 时,Spring 会报错,因为 JSP 将被设置为将表单绑定到“employee”模型属性:

java.lang.IllegalStateException: 
  Neither BindingResult nor plain target object 
    for bean name 'employee' available as request attribute
  at o.s.w.s.s.BindStatus.<init>(BindStatus.java:141)

要访问我们的表单支持对象,我们需要通过*@ModelAttribute*注释注入它。

方法参数上的一个*@ModelAttribute*表示将从模型中检索该参数。如果模型中不存在,则参数将首先实例化,然后添加到模型中。

5. 处理绑定错误

默认情况下,Spring MVC 在请求绑定过程中发生错误时会抛出异常。这通常不是我们想要的,相反,我们应该将这些错误呈现给用户。我们将通过向控制器方法添加一个作为参数来使用BindingResult

public String submit(
  @Valid @ModelAttribute("employee") Employee employee,
  BindingResult result,
  ModelMap model)

BindingResult参数需要放置在我们的表单支持对象之后——这是方法参数的顺序很重要的罕见情况之一。否则,我们将遇到以下异常:

java.lang.IllegalStateException: 
  Errors/BindingResult argument declared without preceding model attribute. 
    Check your handler method signature!

现在——不再抛出异常;相反,错误将在传递给submit方法的BindingResult上注册。此时,我们可以通过多种方式处理这些错误——例如,可以取消操作:

@RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
public String submit(@Valid @ModelAttribute("employee")Employee employee, 
  BindingResult result,  ModelMap model) {
    if (result.hasErrors()) {
        return "error";
    }
    
    //Do Something
    return "employeeView";
}

请注意,如果结果包含错误,我们如何将另一个视图返回给用户,以便正确显示这些错误。让我们看一下那个view——error.jsp

<html>
    <head>
    </head>
    <body>
        <h3>Please enter the correct details</h3>
        <table>
            <tr>
                <td><a href="employee">Retry</a></td>
            </tr>
        </table>
    </body>
</html>

6. 显示Employee

最后,除了创建一个新员工之外,我们还可以简单地显示一个——这是它的快速查看代码:

<body>
    <h2>Submitted Employee Information</h2>
    <table>
        <tr>
            <td>Name :</td>
            <td>${name}</td>
        </tr>
        <tr>
            <td>ID :</td>
            <td>${id}</td>
        </tr>
        <tr>
            <td>Contact Number :</td>
            <td>${contactNumber}</td>
        </tr>
    </table>
</body>

JSP 页面只是使用 EL 表达式来显示模型中 Employee 对象的属性值。

7. 测试应用程序

可以部署简单的应用程序(例如在 Tomcat 服务器中)并在本地访问:http://localhost:8080/spring-mvc-xml/employee

这是包含主表单的视图——在提交操作之前:
/uploads/spring_mvc_form_tutorial/3.png Spring MVC 表单示例——提交

提交后显示数据: /uploads/spring_mvc_form_tutorial/5.png Spring MVC 表单示例 – 查看

就是这样——一个使用 Spring MVC 的简单表单的工作示例,带有验证