1.基础表单标签
准备工作:建立struts2tag项目,搭建好struts2的开发环境。在html我们常用的基础表单标签主要有文本域、密码域、提交、重置四种。它们在strust2中可以通过标签来生成。下面建立login.jsp页面,与这四种标签相关的内容如下:
<%@ page language="java" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <html> <body> <s:form action="login" method="post" namespace="/my"> <s:textfield label="用户名" name="user.username" required="true" requiredposition="right"/> <s:password label="密码" name="user.password" required="true" /> <s:reset value="重置" align="left"/> <s:submit value="注册" align="left"/> </s:form> </body> </html>
说明:label中的内容是显示在表单前的提示内容,required设为true,表示此表单项为必填内容。
2.单选按钮和复选框:
<s:radio list="#{1:'男',0:'女'}" value="1" label="性别" name="user.sex"/> <s:checkboxlist list="#{1:'足球',2:'排球',3:'蓝球',4:'网球'}" name="user.love" label="爱好"/>
3.三种方式实现下拉列表
<s:bean id="p" name="com.asm.NativePlaceFormAction"></s:bean> <s:bean name="com.asm.NativePlaceMapFormAction" id="pMap"></s:bean> <s:bean name="com.asm.NativePlaceProFormAction" id="pp"></s:bean> <s:select list="#p.place" label="籍贯" name="user.place"/> <s:select list="#pMap.place" label="籍贯2" name="user.place"/> <s:select list="#pp.place" listKey="pId" listValue="pName" label="籍贯3" name="user.place" headerKey="-1" headerValue="---省---" emptyOption="true"/>
说明:三种方式实现下拉列表分别对应了三个java类,这三个类的内容为:
NativePlaceFormAction主要代码为:
package com.asm; public class NativePlaceFormAction extends ActionSupport { private List<String> place; public NativePlaceFormAction(){ place=new ArrayList<String>(); place.add("山东省"); place.add("山西省"); place.add("河南省"); place.add("河北省"); place.add("四川省"); place.add("云南省"); } ...省略place的get/set方法 }
NativePlaceMapFormAction主要代码为:
package com.asm; public class NativePlaceMapFormAction extends ActionSupport { private Map<Integer, String> place; public NativePlaceMapFormAction() { place = new HashMap<Integer, String>(); place.put(1, "山东省"); place.put(2, "山西省"); place.put(3, "河南省"); place.put(4, "河北省"); place.put(5, "四川省"); place.put(6, "云南省"); } ...省略place的get/set方法 }
NativePlaceProFormAction主要代码为:
package com.asm; public class NativePlaceProFormAction extends ActionSupport { private List<Object> place; public NativePlaceProFormAction(){ place=new ArrayList<Object>(); new Province(1,"山东省","济南"); place.add(new Province(1,"山东省","济南")); place.add(new Province(2,"山西省","太原")); place.add(new Province(3,"河南省","郑洲")); place.add(new Province(4,"河北","石家庄")); place.add(new Province(5,"四川","成都")); place.add(new Province(6,"云南","昆明")); } ...省略place的get/set方法 }
说明:此三种实现效果一样,但是在它们提交时传递给服务器的参数不同,具体可以参看login.jsp页面的源码。另外,这三种实现其实都依赖了<s:bean>设定的对象,如果我们不希望依赖<s:bean>来设定,
可以通过配置action来实现:下面我们以NativePlaceFormAction说明:首先在struts.xml中配置此action,配置内容如下
<action name="npf" class="com.asm.NativePlaceFormAction"> <result>/login2.jsp</result> </action>
随后,我们在login.jsp中增加如下内容:
<a href="<%=request.getContextPath()%>/my/npf.action">另一个注册页面</a>
其中login2.jsp中的关键内容为:
<s:select list="place" label="籍贯" name="user.place"/>
我们可以发现:在login2.jsp中填写list的值时并没有用ognl表达式,因为我们通过npf.action来访问时,此Action已经被写入到了值栈中,所以我们可以直接引用。
<s:select list="place" label="籍贯" name="user.place"/>place不用加#号了
后面所用到的实例,我们都会把这样的类做成Action,这样如果我们想通过这种方式访问便只需要在struts.xml中配置即可
4.二级联动
<s:bean name="com.asm.TwoSelectAction" id="ts"></s:bean> <s:doubleselect list="#ts.place" listKey="pId" listValue="pName" name="user.place" doubleList="#ts.citys[top]" doubleListKey="cId" doubleListValue="cName" doubleName="user.city" label="籍贯4(二级联动)"> </s:doubleselect>
它所依赖的TwoSelectAction类的主要代码如下:
package com.asm; public class TwoSelectAction extends ActionSupport { private List<Province> place; private Map<Province,List<City>> citys; ...省略place 、citys中get/set方法 public TwoSelectAction(){ place= new ArrayList<Province>(); citys=new HashMap<Province,List<City>> (); Province p1=new Province(1,"山东省","济南"); Province p2=new Province(2,"山西省","太原"); Province p3=new Province(3,"河南省","郑洲"); Province p4=new Province(4,"河北","石家庄"); Province p5=new Province(5,"四川","成都"); Province p6=new Province(6,"云南","昆明"); place.add(p1); place.add(p2); place.add(p3); place.add(p4); place.add(p5); place.add(p6); //山东省的市: City c1=new City(1,"济南"); City c2=new City(2,"招远市"); City c3=new City(2,"寿光市"); List p1City=new ArrayList(); p1City.add(c1); p1City.add(c2); p1City.add(c3); //山西省的市: City c4=new City(4,"太原市"); City c5=new City(5,"大同市"); City c6=new City(6,"晋中市"); List p2City=new ArrayList(); p2City.add(c4); p2City.add(c5); p2City.add(c6); //河南省的市: City c7=new City(7,"郑州市"); City c8=new City(8,"卫辉市"); City c9=new City(8,"信阳市"); List p3City=new ArrayList(); p3City.add(c7); p3City.add(c8); p3City.add(c9); //河北省的市: City c10=new City(10,"石家庄"); City c11=new City(11,"晋州市"); City c12=new City(12,"鹿泉市"); List p4City=new ArrayList(); p4City.add(c10); p4City.add(c11); p4City.add(c12); //四川省的市: City c13=new City(13,"成都"); City c14=new City(14,"南充"); City c15=new City(15,"绵阳"); List p5City=new ArrayList(); p5City.add(c13); p5City.add(c14); p5City.add(c15); //云南省的市: City c16=new City(16,"昆明市"); City c17=new City(17,"安宁市"); City c18=new City(18,"曲靖市"); List p6City=new ArrayList(); p6City.add(c16); p6City.add(c17); p6City.add(c18); citys.put(p1,p1City ); citys.put(p2,p2City ); citys.put(p3,p3City ); citys.put(p4,p4City ); citys.put(p5,p5City ); citys.put(p6,p6City ); } }
简要分析:此实例有些繁琐,主要思想:我们的place对象主要为一级列表服务,只要理解了前面的下拉列表,这里不难理解一级列表。而二级列表中我们使用#ts.citys[top]取出的一个List对象,这样也正是下拉列表所要求的对象类型(List,Map),而top是非常关键的,它明确指出我们取出的是栈顶的对象,这样就能根据一级列表的值来动态生成这个List对象。
5.其它表单标签
<s:select name="singer" list="{}" label="歌星" headerKey="0" headerValue="--歌手名单--" emptyOption="true"> <s:optgroup list="#{1:'任贤齐',2:'刘德华',3:'周杰伦'}" label="男歌手"/> <s:optgroup list="#{1:'萧亚轩',2:'蔡依林',3:'she'}" label="女歌手"/> </s:select>
<s:combobox label="来源调查" list="{'朋友介绍','电视广告','网络广告'}" name="from" /> <s:updownselect list="{'java','C#','VC','php','vb','vc','python'}" moveDownLabel="下移一位" moveUpLabel="上移一位" selectAllLabel="全部选中" label="您常用编程语言排名" /> <s:optiontransferselect leftTitle="选择喜欢做的事:" list="{'听歌','看电影','编程','玩游戏','chat'}" name="love" headerKey="0" headerValue="喜欢做的事" emptyOption="true" rightTitle="选择讨厌做的事:" doubleList="{'跳舞','唱歌','打篮球','旅游','shopping'}" doubleName="hate" doubleHeaderKey="0" doubleHeaderValue="不喜欢的事" doubleEmptyOption="true" label="个人兴趣说明" leftUpLabel="上移" leftDownLabel="下移" rightUpLabel="上移" rightDownLabel="下移" addToLeftLabel="<—添加" addToRightLabel="添加—>" addAllToLeftLabel="<—添加(All)" addAllToRightLabel="添加(All)—>" selectAllLabel="全选" /> <s:checkbox label="接受服务条款" value="false" name="user.accept"/>
有了前面的标签学习,这些标签很容易理解,只需结合显示效果和查看源码来加深它们的理解。但是特别要注意的是<s:checkbox>标签与</s:checkboxlist>的区别。
补充:使用struts2生成的表单标签会在标签内嵌套一些特殊的格式,在使用了struts2生成的标签所在网页内查看源代码可以发现多了一些如<tr><td>这样的格式化代码。如果不想struts2增加这些多余的格式化代码,可以在struts.xml中配置如下内容:
<!-- struts2生成的表单标签使用默认的主题,即不附加格式化标签 --> <constant name="struts.ui.theme" value="simple"/>
6.其它常用标签的使用(代码参名为“补充”的文件夹下的tag.jsp)
(1)<s:set>标签
此标签主要用于设置一些属性值。
Scope:指定变量被设置的范围,该属性可以接受application、session、request、page或Action。如果没有设置该属性,则默认放置在OGNL Context中,我们可以通过#号来引用。
Value:赋给变量的值,如果没有设置该属性,则将ValueStack栈顶的值赋给变量。
Id/name/var:属性的引用名称,id/name均过时,建议用var来取代他们。
(2)<s:property>
Default:可选属性,如果需要输出的属性值为null,则显示属性指定的值
Escape:可选属性,指定是否格式化html代码。
Value:可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值
Id:可选属性,指定该元素的标识
(3)<s:Iterator>
Value:可选属性,指定迭代的集合,如果没有指定该属性,则使用ValueStack栈顶的集合
Id:可选属性,指定集合里元素的id(已被标记为过时)
Status:可选属性,该属性指定迭代时当前迭代对象的一个实例,并把此实例放在ognl的上下文中,我们可以通过#号来引用这个实例。该实例包含如下几下方法:
Int getCount:返回当前迭代了几个元素。
Int getIndex:返回当前被迭代的元素的索引
Boolean isEven:返回当前被迭代的元素的索引是否是偶数
Boolean isOdd:返回当前被迭代的元素的索引是否是奇数
Boolean isFirst:返回当前被迭代的元素是否是第一个元素
Boolean isLast:返回当前被迭代的元素是否是最后一个元素
说明:因为iterator会把每次迭代的实例放在值栈的栈顶,而<s:property>默认访问的是值栈的栈顶元素。所以如下代码可行:
<s:set var="list" value="{'第一个','第二个','第三个'}"/> <!-- iterator迭代的特点:会把迭代的对象放到值栈的栈顶 --> <s:iterator value="#list"> <s:property/> </s:iterator>
如果想用status来实现一些功能,可参下面的代码:
<br/>-------------------奇数红色,偶数蓝色---------------<br/> <s:iterator value="#list" status="i"> <font color='<s:if test="#i.even">blue</s:if><s:else>red</s:else>' > <s:property/> </font><br/> </s:iterator>
(4)url标签
<br/><br/>-----------使用url---------------<br/> <s:set var="age" value="25" scope="request"/> <s:url action="asm" namespace="/" > <s:param name="age" value="#request.age"></s:param> </s:url>
说明:它会根据action及namespace并附加上下文路径构建一个链接。
<br/><!-- value的值中一定要用单引号引起,这样才表示它的值是一个字串 --> <s:set var="bdUrl" value="'http://www.baidu.com'" /> <s:url value="#bdUrl" /> <br/> <s:url value="%{#bdUrl}" />
说明:由于url标签的value属性默认不支持ognl,所以我们要使用%{}来表示{}中的#bdUrl是一个ognl表达式。