6. 示例 05 – 输入表单
我们将通过一个简单示例来介绍输入表单的概念。
6.1. NetBeans 项目
![]() |
在 [1] 中,该项目:
- 视图 [Saisie.jsp]、[Confirmation.jsp]
- 配置文件 [struts.xml]
- 消息文件 [messages.properties]
- 动作 [Confirm.java]
在 [2] 中,入口页面
6.2. 配置
[struts.xml] 文件内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- internationalization -->
<constant name="struts.custom.i18n.resources" value="messages" />
<!-- default package -->
<package name="default" namespace="/" extends="struts-default">
<default-action-ref name="index" />
<action name="index">
<result type="redirectAction">
<param name="actionName">Saisir</param>
<param name="namespace">/actions</param>
</result>
</action>
</package>
<!-- equity package -->
<package name="actions" namespace="/actions" extends="struts-default">
<action name="Saisir">
<result name="success">/vues/Saisie.jsp</result>
</action>
<action name="Confirmer" class="actions.Confirmer">
<result name="success">/vues/Confirmation.jsp</result>
</action>
</package>
</struts>
- 第 20 行:URL /actions/Action 的操作包。
- 第 21–23 行:定义 [Enter] 操作。该操作未关联任何类。响应始终为视图 [/views/Enter.jsp]
- 第 24–26 行:定义 [Confirm] 操作。该操作关联了 [actions.Confirm] 类。响应始终是视图 [/views/Confirmation.jsp]
6.3. [确认] 操作
其代码如下:
package actions;
import com.opensymphony.xwork2.ActionSupport;
public class Confirmer extends ActionSupport{
// model
private String nom;
// getters and setters
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
}
该类仅有一个字段,即第 8 行中的字段及其 get/set 方法。
6.4. 消息文件
[messages.properties] 的内容如下:
saisie.texte=Formulaire de saisie
saisie.titre1=Saisie
saisie.titre2=Saisie
saisie.libelle=Tapez votre nom
saisie.valider=Valider
confirm.titre1=Confirmation
confirm.titre2=Confirmation
confirm.texte=Bonjour
confirm.retour=Retour au formulaire de saisie
这些消息键在 [Entry.jsp] 和 [Confirmation.jsp] 视图中均被使用。
6.5. 视图
6.5.1. [Entry.jsp] 视图
从视觉上看,它如下所示:
![]() |
其源代码如下:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="saisie.titre1"/></title>
</head>
<body>
<h1><s:text name="saisie.titre2"/></h1>
<s:form action="Confirmer">
<s:textfield key="saisie.libelle" name="nom"/>
<s:submit key="saisie.valider" action="Confirmer"/>
</s:form>
</body>
</html>
- 第 7 行:显示键“saisie.titre1”的消息(输入)[1]。
- 第 10 行:显示键 "saisie.titre2"(输入)的提示信息 [2]。
- 第 11、14 行:<s:form> 标签定义了一个 HTML 表单。该表单中的所有输入内容都将发送至 Web 服务器。我们称其为“POST”数据,是因为将数据发送至服务器的 HTTP 操作称为 POST。数据以字符串形式发送:param1=value1¶m2=value2&... 我们已经在示例 02 的第 3.5 节中遇到过这种字符串。 在这两种情况下,Struts 2 都会以相同的方式处理参数字符串。参数的值会被注入到正在执行的 Action 中,并存入与参数同名的字段中。提交的数据会发送给谁?默认情况下,会发送给显示表单的 Action,即这里的 Saisir Action [5]。您也可以使用 action 属性指定另一个 Action,例如这里的 [Confirmer] Action。
- 第 12 行:<s:textfield ...> 标签显示输入字段 [3]。其 key 属性指定了将显示在输入字段左侧的标签键。因此,该标签会在 [messages.properties] 文件中被查找。name 属性是将被提交的参数名称。与该参数关联的值将是输入字段中输入的文本。
- 第 13 行:<s:submit ...> 标签显示按钮 [4]。其 key 属性指定了将显示在按钮上的标签的键名。因此,该标签是从 [messages.properties] 文件中获取的。提交按钮会触发表单向某个操作提交。我们之前提到,由于 <s:form> 标签的 action 属性,此操作是 [Confirm]。 <s:submit> 标签的 action 属性允许您根据需要指定不同的操作。在此,我们将操作设置为 [Confirm]。该按钮有一个默认参数名称:action:action_name,此处为 action:Confirm。与该参数关联的值即为按钮标签。最终,当用户点击 [Validate] 按钮时,提交给 [Confirm] 操作的参数字符串将为:
?name=xx&action:Confirm=Validate。
其中 xx 是用户在输入字段中输入的文本。
6.5.2. [Confirmation.jsp] 视图
从视觉上看,它如下所示:
![]() |
我们输入一个名字并提交表单。随后收到响应 [1],即 [Confirmation.jsp] 视图。显示在 [2] 处的 URL 是 [Confirm] 操作的地址。在上例中,提交了以下字符串:
name=bernard&action:Confirm=Validate
action:Confirm 参数使 Struts 2 能够将请求路由到正确的操作,在本例中即 [Confirm] 操作。随后,name 参数的值将被注入到 [Confirm] 操作的 name 字段中。
[Confirmation.jsp] 动作的源代码如下:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="confirm.titre1"/></title>
</head>
<body>
<h1><s:text name="confirm.titre2"/></h1>
<s:text name="confirm.texte"/>
<s:property value="nom"/> !
<br/><br/>
<a href="<s:url action="Saisir"/>"><s:text name="confirm.retour"/></a>
</body>
</html>
- 第 7 行:显示消息文件 [1] 中找到的键标签 confirm.title1
- 第 10 行:显示消息文件 [3] 中找到的键标签 confirm.title2
- 第 12 行:显示已执行的 [Confirm] 操作的 name 属性。
- 第 14 行:创建指向 [Enter] 操作的链接。我们之前见过的 <s:url> 标签将根据浏览器的 URL [2] 生成。 路径将采用 [2] 中的 http://localhost:8084/exemple-05/actions,而操作则取自 action 属性,本例中为 Enter。因此,链接的 URL 将为 http://localhost:8084/exemple-05/actions/Saisir.action。链接文本将采用与 confirm.retour 键关联的标签 [4]。
6.6. 测试
以下是两个请求:
![]() |
在[1]中输入姓名并提交。在[2]中显示确认页面。
![]() |
在[3]处,我们点击链接返回表单。在[4]处,显示结果。所有内容都已说明,唯独[3]到[4]的过渡过程除外。为什么我们在[4]处看不到之前输入的姓名?
[3] 中的链接指向 URL [http://localhost:8084/exemple-05/actions/Saisir.action]。因此,[提交] 操作被执行。让我们看看 [struts.xml] 中的配置:
<package name="actions" namespace="/actions" extends="struts-default">
<action name="Saisir">
<result name="success">/vues/Saisie.jsp</result>
</action>
<action name="Confirmer" class="actions.Confirmer">
<result name="success">/vues/Confirmation.jsp</result>
</action>
</package>
[Enter] 操作未与任何操作关联。因此,[Entry.jsp] 视图会立即显示。让我们看看该视图的代码:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="saisie.titre1"/></title>
</head>
<body>
<h1><s:text name="saisie.titre2"/></h1>
<s:form>
<s:textfield key="saisie.libelle" name="nom"/>
<s:submit key="saisie.valider" action="Confirmer"/>
</s:form>
</body>
</html>
第 12 行显示了输入字段。其内容通过 name 属性进行初始化。回顾一下前面关于 <s:property> 标签工作原理的说明:
<s:property name="property"> 标签允许您写入名为 ActionContext 的对象的某个属性的值。该对象包含:
- 与已执行操作相关联的类的属性。
- 当前请求的属性,表示为 <s:property name="#request['key']">
- 用户会话的属性,表示为 <s:property name="#session['key']">
- 应用程序本身的属性,表示为 <s:property name="#application['key']">
- 客户端浏览器发送的参数,表示为 <s:property name="#parameters['key']">
- 语法 <s:property name="#attr['key']"> 按页面、请求、会话和应用程序的顺序,依次显示在这些位置中检索到的对象的值。
此处属于情况 1。[Enter] 操作没有关联的类。因此,name 属性不存在。随后,输入字段中将显示一个空字符串。
要在 [4] 中显示 [1] 中输入的名称,我们将使用用户的会话。




