Struts中的标签可分为2类:
- 通用|普通标签 包括流程控制标签、数据访问标签
- UI标签 包括表单标签、非表单标签
Struts2中的标签均带有前缀s。
常用的流程控制标签
1、if-elseif-else标签 条件判断
<s:set var="score" value="95" scope="request" /> <s:if test="#request.score>=80">优秀</s:if> <s:elseif test="#request.score>=60">及格</s:elseif> <s:else>不及格</s:else>
test指定条件,满足条件时,显示标签体的内容。
2、iterator标签 迭代Array、List、Map
<% List<User> list=new ArrayList<>(); list.add(new User("刘备", 28)); list.add(new User("关羽", 25)); list.add(new User("张飞", 18)); request.setAttribute("list",list); %> <table> <s:iterator var="user" value="#request.list"> <tr> <td><s:property value="#user.name" /></td> <td><s:property value="#user.age" /></td> </tr> </s:iterator> </table>
var指定临时变量,代表一项,value指定Array | List | Map 。
在标签体中可直接使用临时变量。但不能这样访问:
<td>user.name</td> <td>#user.name</td> <td>%{#user.name}</td>
常用的数据访问标签
<s:debug /> <s:set var="group" value="vip" scope="session" /> <s:property value="#request.list" /> <s:include value="xxx.jsp" />
<s:debug>会在页面上生成一个调试链接,可查看ValueStack中的数据。
<s:set>用于向某个域中存入数据,相当于setAttribute(),var指定参数的name,value指定参数的value。
<s:property>用于输出ValueSatck中的数据,value指定要输出的数据,只能使用OGNL表达式,不能使用常量,比如value=”ok‘”是无效的。
<s:include>用于包含其他的JSP页面。
常用的表单标签
<s:form action="" method=""> <s:textfield name="user" value="" label="用户名" /> <s:password name="pwd" value="" label="密码" /> <s:textarea name="comment" rows="10" cols="40" label="评论" value="" /> <s:radio name="gender" list="#{'male':'男','female':'女'}" label="gender" /> <s:checkboxlist name="hobby" list="#{'basketball':'篮球','running':'跑步','swimming':'游泳'}" label="爱好" /> <s:checkbox name="hobby" value="basketball" label="篮球" /> <s:checkbox name="hobby" value="running" label="跑步" /> <s:checkbox name="hobby" value="swimming" label="游泳" /> <s:select name="" list="#{'zk':'专科','bk':'本科','ss':'硕士','bs':'博士','qt':'其它'}" label="学历" /> <s:select name="" list="#{'zk':'专科','bk':'本科','ss':'硕士','bs':'博士','qt':'其它'}" label="学历" headerKey="" headerValue="--请选择--" /> <s:file name="" /> <s:hidden name="" value="" /> <s:submit value="提交" /> <s:reset value="重置" /> </s:form>
<s:textarea>的默认值是写在value中的,这点与html的文本域不同。
list属性可以写成List,也可以写成Map。写成List时,value属性值、选项文字都是List的元素;写成Map时,value属性值是Map的key,选项文字是Map的value。
可以用<s:checkboxlist>组合一组复选框,以数组形式提交。
也可以逐个写<s:checkbox>,各自提交。
<s:select name="" list="#{'zk':'专科','bk':'本科','ss':'硕士','bs':'博士','qt':'其它'}" label="学历" headerKey="" headerValue="--请选择--" />
header即下拉列表中显示的选项(第一项),headerKey指定第一项的value,headerValue指定第一项的显示文字。
Struts2只提供了常用的表单标签,没有提供日期选择器、颜色选择器等标签。
命名空间
如果struts.xml中设置命名空间:
<package name="action" namespace="/action" extends="struts-default"> <action name="LoginAction" class="action.LoginAction"> <result name="success">/index.jsp</result> <result name="error">/login.jsp</result> </action> </package>
可以这样写action:
<s:form action="LoginAction" namespace="/action" >
</s:form>
不提倡这样写:
<s:form action="action/LoginAction"> </s:form>
第一次提交,地址栏是action/LoginAction;
如果填写有问题,转回此页面重新填写,点击提交,地址栏变为action/action/LoginAction!
如果填写还有问题,再次转回此页面重新填写,点击提交,地址栏变为action/action/action/LoginAction!
……
如果只提交一次,没有问题;如果重复提交多次,会有一点小问题。
只是地址栏变了,其实仍是action/LoginAction处理的。前一种更让人放心。
可以给表单设置主题样式:
<s:form action="" theme="xhtml"> </s:form>
主题默认为xhtml,每个表单元素都显示为块级,前后自动换行。
尽量用xhtml,其他自带的主题不好控制效果。在xhtml主题的基础上,可以使用cssClass、cssStyle,通过css样式来改变界面。
其实Struts2标签不常用,因为不好控制样式,一般都是用html标签。
表单元素常设置的属性:
<s:textfield title="ok" readonly="true" disabled="true" required="true" cssClass="red" cssStyle="color: red;font-size: 18px;"
onclick=""
/>
title指定提示文字,鼠标移上去时会显示提示文字。
readonly、disabled、required的设置方式和html的不同。required为true,提交时会检查是否已填写此字段,未填写会提示。
cssClass指定要引用的类选择器,可以引用Struts2内置的样式,也可以引用自定义的CSS样式。
cssStyle写行内样式。
可以使用事件属性。
数据回显
<action name="LoginAction" class="action.LoginAction">
<result name="success">/index.jsp</result>
<result name="error">/login.jsp</result>
</action>
提交的表单通不过检查时,通常会转发给表单页面重新填写。
html标签会丢失所有的表单数据,需要重新填一遍。Struts2标签仍保留表单数据,会自动填写上次提交的表单。
数据回显的原理:Action处理完业务,调用表单页面,此时ValueStack还没被销毁,会自动调用getter方法取出ValueStack中的表单数据,填写表单。
需要给表单字段对应的属性设置getter方法,否则不能回显。
<s:password>密码字段默认不会回显,如需回显,需要设置showPassword属性为true:
<s:password name="pwd" showPassword="true"/>
防止重复提交表单
刷新页面可能会重新提交表单,造成表单的重复提交。Struts2可以防止表单的重复提交。
在表单中增加<s:token />元素:
<s:form action="LoginAction">
<s:token />
<s:submit value="提交" />
</s:form>
在处理此表单的Action的配置中使用token拦截器:
<action name="LoginAction" class="action.LoginAction"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="token"></interceptor-ref> <result name="success">/index.jsp</result> <result name="error">/login.jsp</result> </action>
在struts.xml中,如果此Action没配置拦截器,默认会使用struts-default.xml中配置的默认拦截器栈。
默认拦截器栈是对请求进行常规的预处理操作,一般都需要。
如果我们在struts.xml中给此Action配置了拦截器,就不会再使用默认的拦截器栈,所以我们需要显式引用默认的拦截器栈。
原理:
<s:token />本质是在表单中添加一个name=”struts.token”的隐藏域,设置一个唯一标识此次表单提交的value,
token拦截器取出这个隐藏域的参数,和session中的struts.token比较,value相同就是重复提交,直接pass调本次请求,不再调用action来处理;
value值不同,说明不是重复提交,会将这个srtuts.token值放到session中,覆盖原有的值,并调用action来处理请求。
如果使用了token拦截器,但一次都没有使用<s:token />标签,提交表单后,token拦截器获取的value为null,session中的value也是null,相同,便不会调用action来处理,相当于提交不了表单。
没有使用<s:token />标签,就不要使用token拦截器。