9. MVC Web 应用程序 [person] – 第 4 版
此版本使用了前面介绍的 JSTL 标签库。
9.1. Eclipse 项目
要为 Web 应用程序 [/personne4] 创建 Eclipse 项目 [mvc-personne-04],请按照第 78 页第 6.2 节所述的步骤复制 [mvc-personne-03] 项目。
![]() | ![]() |
9.2. 配置 [personne4] Web 应用程序
/personne4 应用程序的 web.xml 文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>mvc-personne-04</display-name>
...
除第 6 行外,此文件与上一版本中的文件完全相同,该行中 Web 应用程序的显示名称已更改为 [mvc-personne-04]。
主页 [index.jsp] 发生如下变化:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<c:redirect url="/main"/>
- 第 5 行:页面 [index.jsp] 将客户端重定向至 URL [/main],该 URL 指向应用程序 [/personne4] 的控制器 [ServletPersonne]。<c:redirect> 标签属于 JSTL / Core 库。它具有一项特殊功能,即通过添加:
- 前缀 [/context],其中 [context] 表示应用程序上下文,本例中为 [personne4]。
- 后缀 [?jsessionid=id_session](如果发起请求的浏览器未发送会话 Cookie)。标识符 [jsessionid] 指代 Web 服务器发送给客户端的会话令牌标识符。它取决于具体的 Web 服务器。此处采用的是 Tomcat 服务器的标识符。[id_session] 即会话令牌本身。
因此,[index.jsp] 第 5 行中的实际重定向 URL 是 [/person4/main?jsessionid=XX],其中 XX 是会话令牌。如下图所示,这是在最初请求 URL [http://localhost:8080/personne4] 后获得的页面:

<c:redirect> 标签与会话令牌之间的关系相当微妙。现在深入探讨还为时过早,但我们稍后会有机会再次探讨。
9.3. 视图代码
9.3.1. [表单]视图
该视图未作更改:

它由以下 JSP 页面 [formulaire.jsp] 生成:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<html>
<head>
<title>Personne - formulaire</title>
<script language="javascript">
...
</script>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form name="frmPersonne" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="${nom}" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="${age}" type="text" size="3"></td>
</tr>
<tr>
</table>
<table>
<tr>
<td><input type="submit" value="Submit"></td>
<td><input type="button" value="[Envoyer]" onclick="envoyer()"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="button" value="[Effacer]" onclick="effacer()"></td>
</tr>
</table>
<input type="hidden" name="action" value="validationFormulaire">
</form>
</center>
</body>
</html>
最新动态:
- 第 4 行:声明 JSTL / Core 标签库
- 第 21、25 行:从页面模板中获取 [name, age] 属性。请注意,系统将依次在 JSP 页面的请求、会话和应用程序中搜索这些属性。在本例中,控制器会将它们存入会话中。
- 由于之前的实现,JSP 页面开头不再包含用于获取页面模型的 Java 代码。
9.3.2. 视图 [响应]
此视图未发生变化:
![]() | ![]() |
新的 JSP 页面 [response.jsp] 如下所示:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Personne - réponse</h2>
<hr>
<table>
<tr>
<td>Nom</td>
<td>${nom}</td>
</tr>
<tr>
<td>Age</td>
<td>${age}</td>
</tr>
</table>
<br>
<form name="frmPersonne" method="post">
<input type="hidden" name="action" value="retourFormulaire">
</form>
<a href="javascript:document.frmPersonne.submit();">
${lienRetourFormulaire}
</a>
</body>
</html>
最新动态:
- 第 4 行:声明 JSTL / Core 标签库
- 第 16、20、28 行:在页面模板中获取 [name、age、formSubmitLink] 属性。JSP 页面顶部不再需要任何 Java 代码来获取这些属性。
9.3.3. [errors] 视图
此视图未发生变化:
![]() | ![]() |
新的 JSP 页面 [errors.jsp] 如下所示:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Les erreurs suivantes se sont produites</h2>
<ul>
<c:forEach var="erreur" items="${erreurs}">
<li>${erreur}</li>
</c:forEach>
</ul>
<br>
<form name="frmPersonne" method="post">
<input type="hidden" name="action" value="retourFormulaire">
</form>
<a href="javascript:document.frmPersonne.submit();">
${lienRetourFormulaire}
</a>
</body>
</html>
最新动态:
- 第 4 行:声明 JSTL / Core 标签库
- 第 13–15 行:使用 JSTL 显示错误列表
- JSP 页面顶部不再包含用于获取其模板的 Java 代码。
9.4. 视图测试
要测试上述视图,我们将它们的 JSP 页面复制到 Eclipse 项目的 /WebContent/JSP 文件夹中:

然后,在 JSP 文件夹中,对页面进行如下修改:
[form.jsp]:
...
<%
// -- test : on crée le modèle de la page
session.setAttribute("nom","tintin");
session.setAttribute("age","30");
%>
<html>
<head>
第4–5行是为创建该页面所需的模板而添加的。
[response.jsp]:
...
<%
// -- test : on crée le modèle de la page
request.setAttribute("nom","milou");
request.setAttribute("age","10");
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<html>
<head>
...
第4至6行是为生成该页面所需的模板而添加的。
[errors.jsp]:
<%
// -- test : on crée le modèle de la page
ArrayList<String> erreurs1=new ArrayList<String>();
erreurs1.add("erreur1");
erreurs1.add("erreur2");
request.setAttribute("erreurs",erreurs1);
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<html>
<head>
第4至8行是为生成该页面所需的模板而添加的。
如果尚未启动 Tomcat,请先启动它,然后访问以下 URL:
![]() | ![]() |
![]() |
我们获得了预期的浏览量。
9.5. [ServletPersonne] 控制器
[/personne3] Web 应用程序的 [ServletPersonne] 控制器将处理以下操作:
否。 | 请求 | 来源 | 处理 |
1 | [GET /person4/main] | 用户输入的 URL | - 发送空的 [form] 视图 |
2 | [POST /person4/hand] 并携带参数 [txtName, txtAge, action=validateForm] 已发布 | 点击 [提交] 按钮 [表单] | - 检查 [txtName, txtAge] 参数的值 - 若值不正确,则发送 [errors(errors)] 视图 - 如果值正确,则返回 [response(name,age)] 视图 |
3 | [POST /person4/main] 带参数 [action=returnForm] 已提交 | 点击 [返回 表单] [响应]和[错误]中。 | - 发送已预先填入最新输入值的 [表单] 视图 |
[ServletPersonne] 控制器的骨架与上一版本完全相同。我们将回顾对 [doInit、doValidationFormulaire、doRetourFormulaire] 方法所做的修改;[init、doGet、doPost] 方法保持不变。
9.5.1. [doInit] 方法
该方法处理请求 #1 [GET /personne4/main]。其代码如下:
新增内容:
- 第 3 行:渲染 [form] 视图。该视图期望其模板中包含 "name" 和 "age" 属性。由于控制器未提供这些属性,因此视图无法找到它们。 在这种情况下,JSTL 库将为这些属性检索 null 指针。这不会引发任何错误,且 [form] 视图中的 ${name} 和 ${age} 元素将显示为空值。这正是我们所需要的。因此,我们无需初始化 [form] 视图的模型。
9.5.2. [doValidationFormulaire] 方法
该方法处理请求 #2 [POST /person4/main],其中提交的元素包含 [action, txtName, txtAge]。其代码如下:
更新内容:
- 第 15 行:[doValidationFormulaire] 方法返回 [response] 视图。该视图的模型中包含 [name、age、formReturnLink] 这三个元素。[formReturnLink] 是通过请求在第 14 行添加到模型中的。[name、age] 这两个元素是通过会话在第 8–10 行放入模型的。 在之前的版本中,我们在发送 [response] 视图时,也曾将 [name, age] 元素放入请求中,因为该视图期望它们位于那里。在此,借助 JSTL 库,我们知道系统会搜索各种上下文(请求、会话、应用程序)来查找模型元素。因此,由于控制器已将它们放入会话中(第 8–10 行),它们将在会话中被找到。
9.5.3. [doRetourFormulaire] 方法
该方法处理第 3 个请求 [POST /person4/main],其提交数据中包含 [action=retourFormulaire]。其代码如下:
新增内容:
- 第 4 行:显示 [form] 视图。该视图期望其模型中包含“name”和“age”这两个属性。它将在会话中找到这些属性,因为 [doValidationForm] 方法已将它们存入会话,而该方法必然在 [doReturnForm] 方法之前执行。 因此,在第 4 行显示 [form] 表单之前,无需初始化其模型。结果,[doInit] 和 [doReturnForm] 方法完全相同,我们可以移除 [returnForm] 操作,并用 [init] 操作替换它。这样,[doReturnForm] 方法就会消失。
9.6. 测试
在此新版本中,仅视图发生了变化。[ServletPersonne] 控制器保持不变。使用 JSTL 仅仅使我们能够更轻松地在 JSP 页面中利用控制器构建的模型。
集成 Eclipse 项目 [personne-mvc-04] 后,启动或重启 Tomcat。访问 URL [http://localhost:8080/personne4]。








