
4.3 Struts 2常用标签
Struts 2框架提供了丰富的标签库用来构建视图组件。Struts 2标签库简化了视图页面的开发,并且提高了视图组件的可维护性。
在JSP页面中使用Struts 2标签,首先要在JSP页面中使用标签库指令,引入Struts 2的标签库,格式如下。
<%@ taglib uri="/struts-tags" prefix="s"%>
在本节中,只介绍最常用的几种标签,对于没有涉及的标签,在项目开发中若需要,可以查看Struts 2官方文档。
4.3.1 Struts 2的通用标签与应用案例
Struts 2的通用标签主要有数据访问、超链接等有关标签,这里介绍最常用的几种。
1.<s:property>标签
该标签用来输出值栈中的指定对象及属性的值,通常与OGNL结合使用。如下面的代码所示。
<s:property value="#request.name"/> 功能:显示对象request中的属性name的值
2.a标签
该标签实现超链接,例如,下面的语句是超链接Action(也可以超链接JSP页面)。
<s:a href="register.action">注册</s:a>
3.<s:param>标签
该标签主要用于为其他标签提供参数,格式如下。
<s:param name="***" value="***"/>
其中,name用于指定需要设置参数的参数名;value用于指定需要设置参数的参数值。
注意:①无论在给出value值时有没有使用%{}, Struts 2都会对它进行ognl求值。②如果要传递String类型的字符串作为参数值,必须用单引号括起来。③可以把value属性的值写在开始标签和结束标签之间,从而可以传递一个EL表达式的值。
4.<s:bean>标签
该标签将创建一个JavaBean对象,并把它压入ContextMap中。在创建JavaBean实例时,可以使用<s:param>标签为JavaBean实例传入参数。格式如下。
<s:bean name="类路径" var="对象名称"> <s:param name="属性名"value="属性值"/> //注意:若为字符串常量必须用单引号括起来 …………….. </s:bean>
其中:name用于指定要实例化的JavaBean的实现类;var用于设置实例名称。
例如,利用【例4-1】中的Person类,在JSP页面中创建对象并显示。其关键代码如下。
<s:bean name="com.edu.ognl.action.Person" var="s" > <s:param name="name" value="'zhangsan'"/> </s:bean> <s:property value="#s.name"/>
运行该JSP页面时,显示结果为zhangsan。
5.<s:set>标签
set标签用来在以下Map对象(ContextMap值栈,session、application和request等域对象)中创建一个键值对。其中ContextMap值栈为默认对象。其常用属性如下。
● name:指定新变量的名称,是必选项。
● scope:指定作用域request、response、session或application。默认值为default。
● value:为新变量赋值,可以是集合值。
(1)创建一个属性并存储
如下面的代码所示。
<s:set name="age" value="20" scope=" request" />
(2)创建一个对象并赋值
例如,利用【例4-1】中的Person类,在JSP页面中创建一个Bean对象,然后再赋值给一个变量并显示该变量的值。其关键代码如下。
<s:bean name="com.edu.ognl.action.Person" id="s" > <s:param name="name" value="'张三'"/> </s:bean> <s:set name="user" value="#s" scope="request"/> scope属性值为request范围:<s:property value="#request.user.name" />
运行该页面时,首先形成对象s(保存在ContextMap子栈内),然后又形成对象user(保存在ContextMap子栈的request对象内),然后显示对象user的值(name属性值)。
(3)创建list集合并存储,在访问单个元素时,可以按其下标(下标从0开始访问)。
如下面的代码所示。
<s:set name="list" value="{'a', 'b', 'c', 'd'}"></s:set>
(4)创建map集合并存储
Map集合的语法格式:#{key:value, key1:value1, key2:value2, .....}
利用该语法,可生成Map类型的集合,该Map对象中的每个key-value对象之间用英文的冒号隔开,多个元素之间用逗号分隔,若是字符串类型,用单引号括起来,如下面的代码所示。
<s:set name="map" value="#{'1':'laowang', '2':'老王', '3':'猩猩'}"></s:set
6.url标签
url标签用来动态地创建一个URL,其常用属性如下。
● action:指定一个Action作为URL地址。
● method:指定使用Action的方法。
● var:指定压入值栈Map的值。
● value:指定生成URL的地址,若缺省,则使用action属性指定值作为URL地址。
● encode:指定编码请求方法。
● names:指定名称空间。
如下面的代码所示。
<s:set name="zhangsan1" value="'aaaa'"/> <s:set name="zhangsan2" value="'bbbb'"/> <s:url action="ognlTest" namespace="/test" var="add"> <! -- 该格式对应于value,按OGNL解析求值--> <s:param name="username1" value="#zhangsan1"/> <! -- 单引号括起来,该格式对应于value,不解析,按字符串常量--> <s:param name="username2" value="'zhangsan2'"/> <s:param name="id">12</s:param> </s:url> <s:url value="/xyz/input.jsp" var="aaa"></s:url> <! -- 使用该URL地址 --> ${add}<br> ${aaa}<br> <s:a href="%{add}">测试URL</s:a>
运行后显示的结果如下(注意输出格式)。
/工程名/test/ognlTest.action? username1=aaaa&username2=zhangsan2&id=12 /工程名/xyz/input.jsp 测试URL(超链接地址)
7.<s:action>标签
该标签用于在页面上执行一个Action,并且还将当前Action对象压入ContextMap子栈。常用属性如下。
● var:指定被调用Action的引用,是可选项。
● name:指定Action的名称,是必选项。
● namespace:指定被调用Action所在的namespace,是可选项。
● executeResult:指定将Action处理结果包含到当前页面中,默认值为false。
● ignoreContextParams:指定当前页面的数据是否需要传给被调用的Action,默认值为false,即默认将页面中的参数传给被调用的Action,是可选项。
例如,在【例4-2】中设计并配置的Action,可以在页面中直接调用执行,语句如下。
<s:action name="ognlTest" namespace="/test"></s:action>
8.<s:date>标签
该标签用于格式化输出日期。该标签有以下几个属性。
● format:若指定该属性值(必须是java.text.SimpleDateFormat类中定义的日期/时间格式之一),将根据该属性指定的格式来格式化日期。
● nice:指定是否输出指定日期和当前时刻之间的时差。默认为false。
● name:属性是必选的,指定要格式化的日期值。
● var:指定格式化后的字符串将被放入ContextMap中。
使用格式如下。
1)按指定日期格式输出:<s:date name="指定日期取值" format="日期格式"/> 2)输出时间差:<s:date name="指定日期取值" nice="true"/> 3)默认格式输出:<s:date name="指定日期取值"/>
例如,date标签的使用(dateTag.jsp)。
<s:bean name="java.util.Date" var="d"> <s:param name="date" value="10"></s:param> </s:bean> (1)nice="false",且指定format="dd/MM/yyyy" <br> <s:date name="#d" format="dd/MM/yyyy" nice="false"/><br> (2)nice="true",且指定format="dd/MM/yyyy" <br> <s:date name="#d" format="dd/MM/yyyy" nice="true"/><br> (3)nice="false",没有指定format属性,指定了var <br> <s:date name="#d" nice="false" var="abc"/> ${requestScope.abc}= =<s:property value="#abc"/>
运行结果如下。
(1)nice="false",且指定format="dd/MM/yyyy" 10/09/2015 (2)nice="true",且指定format="dd/MM/yyyy" 10 days ago (3)nice="false",没有指定format属性,指定了var 2015-9-10 20:42:08= =2015-9-10 20:42:08
9.actionerror和actionmessage标签
actionerror和actionmessage这两个标签都是在页面上输出Action中方法添加的信息。其中,actionerror标签输出的是Action中addActinErrors()方法添加的信息;而actionmessage标签输出的是Action中AddActionMessage()方法添加的信息。
【例4-4】在Action中,利用addActinErrors()方法添加信息;而在JSP中利用actionerror标签和actionmessage标签输出Action中添加的信息。
1)设计添加信息的Action:ActionErrorActionMessage。
package com.edu.ognl.action; import org.apache.struts2.convention.annotation.*; import com.opensymphony.xwork2.ActionSupport; @Namespace("/test") @ParentPackage("struts-default") @Results({ @Result(name = "success", location = "/showErrorActionMessage.jsp") }) public class ActionErrorActionMessage extends ActionSupport { private static final long serialVersionUID = 1L; @Action("messageTest") public String execute() { // 使用addActionError()方法添加信息 addActionError("使用ActionError添加错误信息!"); addActionMessage("使用ActionMessage添加普通信息!"); return SUCCESS; } }
2)设计JSP:showErrorActionMessage.jsp,输出由Action中AddActionMessage()方法添加的信息。
<%@page contentType="text/html" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags"%> <html> <head> <title>actionerror标签和actionmessage标签的使用</title> </head> <body> <s:actionerror/> <s:actionmessage/> </body> </html>
3)启动服务器,在地址栏输入如下请求。
http://localhost:8080/c4_ognl_tag/test/messageTest
运行程序,在页面上将显示如下信息。
使用ActionError添加错误信息! 使用ActionMessage添加普通信息!
4.3.2 Struts 2的控制标签与应用案例
控制标签主要用来完成流程的控制,如条件分支、循环操作等,也可以实现对集合的排序和合并。
1.if、elseif和else标签
这3个标签是用来控制流程的,与Java语言中的if、elseif、else语句相似。在该标签中,使用test属性作为测试条件。例如下面的代码,首先创建一个变量score,并赋值为86,然后利用判定标签,显示相应的信息。在这里,显示“良好”。
<s:set name="score" value="86"/> <s:if test="#score>=90">优秀</s:if> <s:elseif test="#score>=80">良好</s:elseif> <s:elseif test="#score>=70">中等</s:elseif> <s:elseif test="#score>=60">及格</s:elseif> <s:else>不及格</s:else>
2.iterator标签
该标签用于遍历集合,可以遍历一个数组、Collection(List、Set)或Map,并把这个可遍历对象中的每一个元素依次压入和弹出ValueStack栈。格式如下。
<s:iterator value="" var="" status="">…</s:iterator>
其中,常用属性如下。
● value:指定迭代输出的集合对象,可以是OGNL,或通过Action返回的集合。
● var:指定集合中每个元素的引用变量(可选项)。
● status:指定集合中元素的status属性(可选项),且该属性的属性值如表4-1所示。
表4-1 status属性的属性值

1)遍历访问List集合,如下面的代码所示(注意代码中给出的注释说明)。
<! -- 说明:设置set集合(创建list对象并存放到request中),给value赋值;--> <! -- 利用value="#request.list" 获取集合对象,并指定迭代时的IteratorStatus实例,其中 statu.odd返回当前被迭代元素的索引是否是奇数 --> <s:set name="list" value="{'a', 'b', 'c', 'd'}" scope="request">></s:set> <s:iterator var="ent" value="#request.list" status="st"> <font color=<s:if test="#st.odd">red</s:if><s:else>blue</s:else>> <s:property value="#ent" /> </font><br> </s:iterator>
2)遍历访问Map集合,如下面的代码所示(注意代码中给出的注释说明)。
<h3>Map集合</h3> <! -- 说明:Map集合语法格式:#{key:value, key1:value1, key2:value2, .....} 该语法直接生成了一 个Map类型的集合,该Map对象中的每个key-value对象之间用英文的冒号隔开,多个元 素之间用逗号分隔。 首先创建Map对象,然后对Map对象进行遍历,并显示其对应的“健”---“值”--> <s:set var="map" value="#{'1':'张三', '2':'李四', '3':'王五'}"></s:set> 遍历Map:<br /> <s:iterator value="#map"> <s:property value="key"/> --对应于-- <s:property value="value"/><br/> </s:iterator>
3)对集合变量进行遍历访问。
例如,假设users是User的对象集合,并存储在session对象内,age(年龄)是User中的一个属性。
<h3>遍历集合</h3> <! -- 遍历出年龄大于30的所有人员 --> <s:iterator var="user" value="#session.users"> <s:if test="%{#user.age>30}"> <s:property value="#user.age"/> </s:if> </s:iterator> <! --遍历出年龄大于30的最后一名人员。 注意,运算符“$”表示取出满足条件的最后一个值 --> <s:iterator var="u" value="#session.users.{$(#this.age>30)}"> <s:property value="#u.age"/> </s:iterator>
4.3.3 Struts 2的表单标签与应用案例
Struts 2的表单标签将在HTM文档里被呈现为一个表单元素。使用Struts 2的表单标签具有以下优点。
● 可以实现表单回显,对于修改信息特别方便。
● 对页面进行自动布局和排版。
●标签的属性可以被赋值为一个静态的值或一个OGNL表达式,如果在赋值时使用了一个OGNL表达式并把它用%{}括起来,这个表达式将会被求值。
Struts 2中的大部分表单标签和HTML表单元素一一对应,表4-2给出了常用的几个标签,表4-3给出了表单标签的共同属性。
表4-2 Struts 2常用的表单标签

表4-3 表单标签常用的共同属性

1.form标签
form标签用来呈现HTML语言中的表单元素,其主要属性如表4-4所示。
表4-4 form标签的主要属性

在默认情况下,form标签将被呈现为一个表格形式的HTML表单,嵌套在form标签里的输入字段将被呈现为一个表格行,每个表格行由两个字段组成,一个对应行标,一个对应输入元素,提交按钮将被呈现为一个横跨两列单元格的行。
2.textfield标签、password标签和hidden标签
● textfield标签:生成一个单行的文本输入框。
● password标签:生成一个密码域。
● hidden标签:生成一个隐藏域。
语法格式如下。
<s:标签名label="***"name="***"size="***"maxlength="***"/>
其中,label是文本框提示,size是文本框宽度,maxlength是最大字符数。对于password标签有showPassword属性,其属性值是布尔型,默认值为false,决定着在表单回显时是否显示输入的密码。
3.textarea标签:生成一个多行文本框
语法格式如下。
<s:textarea label="***" name="***" cols= "***" rows="***"/>
4.checkbox标签:复选框标签
该复选框元素用于提交一个布尔值,如果该框被选中了,它的值将为true。
语法格式如下。
<s:checkbox label="***" name="***" value="true"/>
5.checkboxlist标签、select标签和radio标签
这3个标签有3个非常重要的属性:list、listKey和listValue。
可以将Map、Lits集合类型的对象赋给list属性;同时可以把用来提供选项值的属性赋给listKey属性,把用来提供选项行标的属性赋给listValue属性(这两个属性相当于Map类型的键值对)。
1)checkboxlist标签:形成多选复选框,如下面的代码所示。
<s:checkboxlist label="个人爱好" list="{'学习', '看电影', '编程序'}" name="love"/>
2)select标签:生成一个下拉列表框,如下面的代码所示。
<s:select label="选择星期" headerValue="---请选择---" headerKey="1" list="{'星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'}"/>
3)radio标签:为一个单选框,如下面的代码所示。
<s: radio label="性别" list="{'男', '女'}" name="sex"></s: radio>
6.file标签
用于在页面上生成一个上传文件的元素。
语法格式如下。
<s:file name="***" label ="***"/>
7.标签的主题
为了让所有的UI标签能够产生同样的视觉效果而归集到一起的一组模板,即风格相近的模板被打包成一个主题。
1)主题类型:在Struts 2中给出了以下几个主题。
● simple:把UI标签翻译成最简单的HTML对应元素,而且会忽视行标属性。
● xhtml:xhtml是默认的主题,使用一个布局表格提供了一种自动化的排版机制。
● css_xhtml:与xhtml主题里的模板很相似,但它们将使用css来进行布局和排版。
● ajax:以xhtml主题里的模板为基础,但增加了Ajax功能。
2)修改主题:通常采用以下方法修改主题。
● 通过UI标签的theme属性。
● 在表单里,若没有给出某个UI标签的theme属性,它将使用这个表单的主题。
●修改struts.properties文件中的struts.ui.theme属性。
【例4-5】 Struts 2的表单标签应用示例。利用Struts 2的表单标签设计下面的JSP页面(在代码中给出了相关的注释),并与如图4-5所示的运行界面对照,理解各标签的使用格式与功能。

图4-5 【例4-5】的运行页面
1)设计界面:form.jsp,其主要代码如下。
<%@ taglib prefix="s" uri="/struts-tags"%> <html><head><title>表单设计演示</title></head> <body> <h3>FORM表单</h3> <s:form action="" name="test"> <s:textfield label="用户名" name="uname"/> <s:password label="密码" name="upass"/> <s:file name="file" label="上传文件"/> <s:hidden name="id" value="1"/> <! -- 基于Map类型,设计列表框 --> <s:select list="#{'1':'博士', '2':'硕士'}" name="edu" label="学历" listKey="key" listValue="value"></s:select> <! -- 基于集合类型,设计列表框,其中,value值设置为默认选中项 --> <s:select label="lanuage"list="{'java', '.net', ''}"value="{'.net'}"></s:select> <! --单选复选框的设计,必须有name --> <s:checkbox label="爱好 "name="checkboxFiled1"value="true"></s:checkbox> <! -- 基于数组类型实现多个checkbox,并指定默认选中项 --> <s:checkboxlist list="{'java', 'css', 'html', 'struts2'}" label="喜欢的编程语言1" name="box" value="{'css', 'struts2'}"></s:checkboxlist> <! -- 基于Map集合实现多选复选框,注意:前要加#,并指定默认选中项--> <s:checkboxlist list="#{1:'java',2:'css',3:'html',4:'struts2',5:'spring'}" label="喜欢的编程语言2" name="boxs" value="{1,2}"></s:checkboxlist> <! --radio标签的使用,并模拟从后台传进选中的默认值 --> <% //从服务器传过来的值用于设置单选按钮的默认值 request.setAttribute("sex", "男"); session.setAttribute("sex1", "1"); %> <s:radio label="性别1" list="{'男', '女'}" name="sex1" value="#request.sex"/> <s:radio label="性别2" list="#{'1':'男', '2':'女'}" name="sex2" listKey="key" listValue="value" value="#session.sex1"></s:radio> <! -- textarea标签的使用 --> <s:textarea name="rmake" cols="40" rows="5" label="备注"/> <! -- 防止表单重复提交的方式 --> <s:token></s:token> <s:submit value="提交"></s:submit> </s:form> </body> </html>
2)运行界面如图4-5所示。