5.4 处理表单

Web 应用的功能通常并不局限于为用户推送内容。大多数的应用允许用户填充表单并将数据提交回应用中,通过这种方式实现与用户的交互。像提供内容一样,Spring MVC 的控制器也为表单处理提供了良好的支持。

使用表单分为两个方面:展现表单以及处理用户通过表单提交的数据。在 Spittr 应用中,我们需要有个表单让新用户进行注册。SpitterController 是一个新的控制器,目前只有一个请求处理的方法来展现注册表单。

程序清单 5.13 SpitterController:展现一个表单,允许用户注册该应用
package spittr.web;
import static org.springframework.web.bind.annotation.RequestMethod.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import spittr.Spitter;
import spittr.data.SpitterRepository;
@Controller
@RequestMapping("/spitter")
public class SpitterController {
@RequestMapping(value="/register", method=GET)
public String showRegistrationForm() {
return "registerForm";
}
}

showRegistrationForm() 方法的 @RequestMapping 注解以及类级别上的 @RequestMapping 注解组合起来,声明了这个方法要处理的是针对 /spitter/register 的 GET 请求。这是一个简单的方法,没有任何输入并且只是返回名为 registerForm 的逻辑视图。按照我们配置InternalResource-ViewResolver的方式,这意味着将会使用 /WEB-INF/views/registerForm.jsp 这个 JSP 来渲染注册表单。

尽管 showRegistrationForm() 方法非常简单,但测试依然需要覆盖到它。因为这个方法很简单,所以它的测试也比较简单。

程序清单 5.14 测试展现表单的控制器方法
@Test
public void shouldShowRegistration() throws Exception {
SpitterController controller = new SpitterController();
MockMvc mockMvc = standaloneSetup(controller).build();
mockMvc.perform(get("/spitter/register")).andExpect(view().name("registerForm"));
}

这个测试方法与首页控制器的测试非常类似。它对 /spitter/register 发送 GET 请求,然后断言结果的视图名为 registerForm。

现在,让我们回到视图上。因为视图的名称为 registerForm,所以 JSP 的名称需要是 registerForm.jsp。这个 JSP 必须要包含一个 HTML <form> 标签,在这个标签中用户输入注册应用的信息。如下就是我们现在所要使用的 JSP。

程序清单 5.15 渲染注册表单的 JSP
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Spitter</title>
<link rel="stylesheet" type="text/css"
href="<c:url value="/resources/style.css" />" >
</head>
<body>
<h1>Register</h1>
<form method="POST">
First Name: <input type="text" name="firstName" /><br/>
Last Name: <input type="text" name="lastName" /><br/>
Email: <input type="email" name="email" /><br/>
Username: <input type="text" name="username" /><br/>
Password: <input type="password" name="password" /><br/>
<input type="submit" value="Register" />
</form>
</body>
</html>

可以看到,这个 JSP 非常基础。它的 HTML 表单域中记录用户的名字、姓氏、用户名以及密码,然后还包含一个提交表单的按钮。在浏览器渲染之后,它的样子大致如图 5.5 所示。

需要注意的是:这里的标签中并没有设置 action 属性。在这种情况下,当表单提交时,它会提交到与展现时相同的 URL 路径上。也就是说,它会提交到 /spitter/register 上。

这就意味着需要在服务器端处理该 HTTP POST 请求。现在,我们在 SpitterController 中再添加一个方法来处理这个表单提交。

图 5.5 注册页提供了一个表单,这个表单会由 SpitterController 进行处理,完成为应用添加新用户的功能