【Java EE (Struts2 + Spring + Hibernate)开发】: Struts2(一)之 【Struts2标签库】
2015-11-24 11:12
459 查看
【Java EE (Struts2 + Spring + Hibernate)开发】: Struts2(一)之 【Struts 2标签库】
本文地址:http://blog.csdn.net/shanglianlm/article/details/50009957
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/0cf5b916f21b68310ce140dc4ec41513)
使用:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/3351255aad1ec226b4d3a10bf3033503)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/feddfa40f18f085ebd9ef81c62cc8014)
命名对象:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/b5328acc5a53ca782488a3872d5a2296)
元素存储在 Stack Context 中,使用这些对象时需要使用 # 前缀来说明。
元素存储在 ValueStack 中,无需书写 # 即可访问 Action 属性。
Struts2中的OGNL详解
Struts2中的OGNL
Map:
^:取出符合选择逻辑的第一个元素。
$:取出符合选择逻辑的最后一个元素。
例
取出 person 的所有性别为 male 的 relatives(亲戚)集合
访问静态成员
例(JSP 页面)
斐波那契数列 求第 11 个元素的值
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/43f2fd511a39ab0915e29fbf570cfd8b)
value:被迭代的集合
id:指定集合里面的元素的id
status 迭代元素的索引
方法:
even : boolean - 如果当前迭代位置是偶数返回true
odd : boolean - 如果当前迭代位置是奇数返回true
count : int - 返回当前迭代位置的计数(从1开始)
index : int - 返回当前迭代位置的编号(从0开始)
first : boolean - 如果当前迭代位置是第一位时返回true
last : boolean - 如果当前迭代位置是最后一位时返回true
modulus(operand : int) : int - 返回当前计数(从1开始)与指定操作数的模数
使用 iterator 迭代 list
使用 iterator 迭代 map
使用s:append标签拼接集合和Map
count属性:指定生成集合中元素的总数。可选属性。
val属性:必填属性,指定被解析的字符串。
separator属性:这是一个必填属性,指定用于分割字符串的分隔符。
converter属性:可选属性,指定一个转换器,转换器负责将生成的集合中的每个字符串转换成对象,通过这个转换器可以将一个含有分隔符的字符串解析成对象的集合。转换器必须一个继承org.apache.struts2.util.IteratorGenerator.Converter的对象。
var属性,可选属性。如果指定了该属性,则将生成的集合保存在Stack Context中。如果不指定该属性,则将生成的集合放入ValueStack的顶端,该标签一结束,生成的集合就被移除。该属性也可替换成id。
使用s:generator生成集合
使用s:generator生成集合
A {1, 2, 3} B{1, 2, 3}
append: 1, 2, 3, 1, 2, 3
merge: 1, 1, 2, 2, 3, 3
count: 可选属性,指定子集中元素的个数.在不指定该属性情况下,默认取得源集合的全部元素
source: 可选属性,指定源集合.若不指定,默认取得ValueStack栈顶的集合.
start:可选属性,指定子集从源集合中的第几个元素开始截取.默认从第一个开始截取,默认值为0
decider:可选属性,指定由开发者自己决定是否选中该元素.
使用s:subset标签截取集合元素
使用s:subset标签自定义标准截取集合元素
comparator: 实现Comparator的类
source: 集合
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/20bf96567e6fff1e1b5b879344441e99)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/47b53706e42b8ba378a9fe54d8b956e1)
id:可选属性,该属性将会作为该Action的引用ID
name:必填属性,指定该标签调用哪个Action
namespace:可选,指定该标签调用的Action所在的namespace.
executeResult:可选,指定是否要将Action的处理结果页面包含到本页面。默认是false,即不包含。
ignoreContextParams:可选,它指定该页面中的请求参数是否需要传入调用的Action、默认是false,即将本页的请求参数传入被调用的Action。
使用s:action标签在页面中调用Action
struts.xml
name:必选属性,指定要实例化的 JavaBean 的实现类。
var:可选属性,如果指定该属性,则该 JavaBean 实例会被放入 Stack Context 中,并放入 requestScope 中。
使用s:bean标签创建JavaBean的实例
format: 可选,如指定该属性,将根据该属性指定的格式来格式化日期
nice: 可选,值为true或者false,用于指定是否输出指定日期和当前时刻的时差。默认是false,即不输出
name: 必填,指定要格式化的日期
var: 可选,如果指定了改属性,则该事件对象将被放到ValueStack中,改属性也可以用id来代替,推荐使用var!
使用s:date标签格式化日期
或
如果为字符串
只有在 push 标签内时,被 push 标签放入 ValueStack 中的对象才存在;一旦离开了 push 标签,则刚刚被放入的元素将立即被移出 ValueStack 。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/b6d54e29fd2fb374267c74b892371509)
s:url来生成一个URL地址
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/ab85a12da3c7625c100c02c1d525c556)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/66db4a51bc4b5bd62ee00e9d34379a04)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/cf9d1f2df1899b84849d2bf58d55c067)
设定主题的方法:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/fa0048a6f31f46fde03507529af6e38d)
前面的优先级高。
模板目录是存放所有模板文件的地方,所有的模板文件以主题的方式来组织,模板目录下有图示目录结构:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/67a35f3a19e33ef07e4eb1f7ba3cf05b)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/17a420db2718bc6ac689a86c0742b707)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/16547206f9454ef74926e11cf1d87302)
struts 2 默认提供了三个主题
simple:最简单的主题,最底层的结构,主要用于构建 HTML UI 组件。
xhtml:struts 2 默认的主题。
css_xhtml:在 xhtml 主题基础上加入了 CSS 样式控制。
从 struts 2.1 开始, struts 2 核心包不再提供 Ajax 主题,而是由 struts2-dojo-plugin-2.2.1.jar 来提供 Ajax 主题。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/8424a87dd8f4600247c7ebc0d7d422e8)
模板相关属性
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/97e32a095c2af9b6d7f3acd6c5a9af3b)
Javascript 相关通用属性
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/a5ac8ad6a315bbaea2096fe0bdf396e6)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/606946e3929d648fb5852fd563266b17)
与 Tooltip 相关的通用属性
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/60172e99c5b1419267d6bb758734361b)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/f611295f1a9560d74b24b93fac2dacee)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/7744b34ae6bde7759a1b7cfdbac6a836)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/72261b031855a637495f58af7371725d)
使用s:checkboxlist生成多个复选框
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/2f682d25f79f0dc241b18da8fc1ae583)
默认情况下,第一个下拉列表框只支持两项,如果第一个下拉列表要包含三项或以上,可以这样实现:
首先定义一个 map 对象,该 map 对象的 value 都是集合,这样就能以 map 对象的多个 key 创建第一个下拉列表框的列表项,而每个 key 对应的集合则用于创建第二个下拉列表框的列表项:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/2ca7138cc972cadf3878c82c7d68c873)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/fe297784d205ae99a8236b0011765fbf)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/3d529013b441f75c35362a5d2791d87b)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/9017658c4e90c093382479fd82970d54)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/45f86e18a44e346ee1ca2b575efd9173)
如果要该标签起作用,则应该在 struts 2 的配置文件中启用 TokenInterceptor 拦截器或 TokenSessionStoreInterceptor 拦截器。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/20/62eaf6fe7ce70050c771feac8a7cde1b)
actionmessage
component
fielderror
theme:自定义组件所使用的主题,如果不指定该属性,默认使用xhtml主题。
templateDir:指定自定义组件的主题目录,如果不指定,默认使用系统的主题目录,即template目录。
template:指定自定义组件所使用的模板。
此外,还可以在 component 标签内使用 param 子标签,向该标签模板传入额外的参数。
使用s:component标签
本文地址:http://blog.csdn.net/shanglianlm/article/details/50009957
1 Struts 2 标签库概述
2 使用 Struts 2 标签
导入:<%@ taglib prefix="s" uri="/struts-tags"%>
使用:
<!-- 使用以 s 作为前缀的标签 --> <s:abc ... />
3 Struts 2 的 OGNL 表达式语言
命名对象:
元素存储在 Stack Context 中,使用这些对象时需要使用 # 前缀来说明。
元素存储在 ValueStack 中,无需书写 # 即可访问 Action 属性。
Struts2中的OGNL详解
Struts2中的OGNL
4 OGNL 中的集合操作
4-1 集合对象:List 和 Map
List:{e1, e2, e3 ...}
Map:
#{key1:value1, key2:value2, ...}
4-2 两个操作运算符: in 和 not in
<!-- 如果指定集合中包含 foo 元素 --> <s:if test="'foo' in {'foo', 'bar'}"> 包含 </s:if> <s:else> 不包含 </s:else> <!-- 如果指定集合中不包含 foo 元素 --> <s:if test="'foo' not in {'foo', 'bar'}"> 包含 </s:if> <s:else> 不包含 </s:else>
4-3 取子集的三个操作符
?:取出所有符合选择逻辑的元素。^:取出符合选择逻辑的第一个元素。
$:取出符合选择逻辑的最后一个元素。
例
person.relatives.{? #this.gender == 'male'}
取出 person 的所有性别为 male 的 relatives(亲戚)集合
5 访问静态成员
在 struts2 中打开 OGNL 访问静态成员方法。<!-- 设置允许 OGNL 允许访问静态成员 --> <constant name="struts.ognl.allowStaticMethodAccess" value="true" />
访问静态成员
@className@staticField @className@staticMethod(val...)
例(JSP 页面)
访问系统环境变量:<s:property value="@java.lang.System@getenv('JAVA_HOME')" /><br /> 圆周率的值:<s:property value="@java.lang.Math@PI" />
6 Lambda 表达式
Lambda (λ) 表达式斐波那契数列 求第 11 个元素的值
<s:property value="#fib =:[#this==0 ? 0 :#this==1 ? 1 : #fib(#this-2) + #fib(#this-1)], #fib(11)" />
7 控制标签
7-1 if/elseif/else 标签
<!-- 在Stack Context中定义一个age属性,其值为29 --> <s:set name="age" value="29"/> <!-- 如果Stack Context中的age属性大于60 --> <s:if test="#age>60"> 老年人 </s:if> <!-- 如果Stack Context中的age属性大于35 --> <s:elseif test="#age>35"> 中年人 </s:elseif> <!-- 如果Stack Context中的age属性大于15 --> <s:elseif test="#age>15"> 青年人 </s:elseif> <s:else> 少年 </s:else>
7-2 iterator 标签
属性:value:被迭代的集合
id:指定集合里面的元素的id
status 迭代元素的索引
方法:
even : boolean - 如果当前迭代位置是偶数返回true
odd : boolean - 如果当前迭代位置是奇数返回true
count : int - 返回当前迭代位置的计数(从1开始)
index : int - 返回当前迭代位置的编号(从0开始)
first : boolean - 如果当前迭代位置是第一位时返回true
last : boolean - 如果当前迭代位置是最后一位时返回true
modulus(operand : int) : int - 返回当前计数(从1开始)与指定操作数的模数
使用 iterator 迭代 list
<table border="1" width="300"> <s:iterator value="{'疯狂Java讲义', '轻量级Java EE企业应用实战', '经典Java EE企业应用实战'}" id="name"> <tr> <td><s:property value="#st.count"/> <s:property value="name"/></td> </tr> </s:iterator> </table>
使用 iterator 迭代 map
<table border="1" width="300"> <!-- 迭代输出List集合 --> <s:iterator value="{'疯狂Java讲义', '轻量级Java EE企业应用实战', '经典Java EE企业应用实战'}" id="name" status="st"> <tr <s:if test="#st.odd"> style="background-color:#bbbbbb"</s:if>> <td><s:property value="name"/></td> </tr> </s:iterator> </table> <table border="1" width="350"> <tr> <th>书名</th> <th>作者</th> </tr> <!-- 对指定的Map对象进行迭代输出,并指定status属性 --> <s:iterator value="#{'疯狂Java讲义':'李刚', '轻量级Java EE企业应用实战':'李刚' , '经典Java EE企业应用实战':'李刚'}" id="score" status="st"> <!-- 根据当前被迭代元素的索引是否为奇数来决定是否使用背景色 --> <tr <s:if test="#st.odd"> style="background-color:#bbbbbb"</s:if>> <!-- 输出Map对象里Entry的key --> <td><s:property value="key"/></td> <!-- 输出Map对象里Entry的value --> <td><s:property value="value"/></td> </tr> </s:iterator> </table>
7-3 append 标签
使用s:append标签拼接两个集合<!-- 使用append标签将两个集合拼接成新的集合, 新集合的名字是newList,新集合放入Stack Context中 --> <s:append var="newList"> <s:param value="{'疯狂Java讲义', '轻量级Java EE企业应用实战', '经典Java EE企业应用实战'}" /> <s:param value="{'http://www.crazyit.org', 'http://blog.crazyit.org'}" /> </s:append> <table border="1" width="260"> <!-- 使用iterator迭代newList集合 --> <s:iterator value="#newList" status="st" id="ele"> <tr> <td><s:property value="#st.count"/></td> <td><s:property value="ele"/></td> </tr> </s:iterator> </table>
使用s:append标签拼接集合和Map
<!-- 使**重点内容**用append将List和Map集合拼接在一起 新集合实际上是Map集合,其名字为newList --> <s:append var="newList"> <s:param value="#{'疯狂Java讲义':'李刚', '轻量级Java EE企业应用实战':'李刚', '经典Java EE企业应用实战':'李刚'}" /> <s:param value="#{'http://www.crazyit.org', 'http://blog.crazyit.org'}" /> </s:append> <table border="1" width="280"> <!-- 使用iterator迭代newList集合 --> <s:iterator value="#newList" status="st"> <tr <s:if test="#st.odd"> style="background-color:#bbbbbb"</s:if>> <td><s:property value="key"/></td> <td><s:property value="value"/></td> </tr> </s:iterator> </table>
7-4 generator 标签
属性count属性:指定生成集合中元素的总数。可选属性。
val属性:必填属性,指定被解析的字符串。
separator属性:这是一个必填属性,指定用于分割字符串的分隔符。
converter属性:可选属性,指定一个转换器,转换器负责将生成的集合中的每个字符串转换成对象,通过这个转换器可以将一个含有分隔符的字符串解析成对象的集合。转换器必须一个继承org.apache.struts2.util.IteratorGenerator.Converter的对象。
var属性,可选属性。如果指定了该属性,则将生成的集合保存在Stack Context中。如果不指定该属性,则将生成的集合放入ValueStack的顶端,该标签一结束,生成的集合就被移除。该属性也可替换成id。
使用s:generator生成集合
<table border="1" width="240"> <!-- 使用generator标签将指定字符串解析成Iterator集合 在generator标签内,得到的List集合位于ValueStack顶端 --> <s:generator val="'疯狂Java讲义 ,轻量级Java EE企业应用实战, 经典Java EE企业应用实战'" separator=","> <!-- 没有指定迭代哪个集合,直接迭代ValueStack顶端的集合 --> <s:iterator status="st"> <tr <s:if test="#st.odd"> style="background-color:#bbbbbb"</s:if>> <td><s:property/></td> </tr> </s:iterator> </s:generator> </table>
使用s:generator生成集合
<!-- 使用generator将一个字符串解析成一个集合 ,指定了var和count属性 --> <s:generator val="'疯狂Java讲义 ,轻量级Java EE企业应用实战, 经典Java EE企业应用实战'" separator="," var="books" count="2"/> <table border="1" width="300"> <!-- 迭代输出Stack Congtext中的books集合 --> <s:iterator value="#books"> <tr> <td><s:property/></td> </tr> </s:iterator> </table> ${requestScope.books}
7-5 merge 标签
merge 和 append很类似,不同之处在于A {1, 2, 3} B{1, 2, 3}
append: 1, 2, 3, 1, 2, 3
merge: 1, 1, 2, 2, 3, 3
7-6 subset 标签
属性count: 可选属性,指定子集中元素的个数.在不指定该属性情况下,默认取得源集合的全部元素
source: 可选属性,指定源集合.若不指定,默认取得ValueStack栈顶的集合.
start:可选属性,指定子集从源集合中的第几个元素开始截取.默认从第一个开始截取,默认值为0
decider:可选属性,指定由开发者自己决定是否选中该元素.
使用s:subset标签截取集合元素
<table border="1" width="300"> <!-- 使用subset标签截取目标集合的4个元素,从第2个元素开始截取 --> <s:subset source="{'疯狂Java讲义' ,'轻量级Java EE企业应用实战' ,'经典Java EE企业应用实战' ,'疯狂Ajax讲义' ,'疯狂XML讲义'}" start="1" count="4"> <!-- 使用iterator标签来迭代目标集合,因为没有指定value属性值, 故迭代ValueStack栈顶的集合 --> <s:iterator status="st"> <!-- 根据当前迭代元素的索引是否为奇数决定是否使用CSS样式 --> <tr <s:if test="#st.odd"> style="background-color:#bbbbbb"</s:if>> <td><s:property/></td> </tr> </s:iterator> </s:subset> </table>
使用s:subset标签自定义标准截取集合元素
//用户自定义的Decider类,实现了SubsetIteratorFilter.Decider接口 public class MyDecider implements SubsetIteratorFilter.Decider { //实现Decider接口必须实现的decide方法, //该方法决定集合中的元素是否被选入子集 public boolean decide(Object element) throws Exception { String str = (String)element; //如果集合元素(字符串)中包含Java EE子串,即可被选入子集 return str.indexOf("Java EE") > 0; } }
<!-- 定义一个Decider Bean --> <s:bean var="mydecider" name="org.crazyit.app.util.MyDecider"/> <!-- 使用自定义的Decider实例来截取目标集合,生成子集 指定var属性,将生成的Itertor放入pageScope中 --> <s:subset source="{'疯狂Java讲义' ,'轻量级Java EE企业应用实战' ,'经典Java EE企业应用实战' ,'疯狂Ajax讲义' ,'疯狂XML讲义'}" decider="#mydecider" var="newList"/> 直接输出page范围的newList属性:<br/> ${pageScope.newList} <table border="1" width="240"> <!-- 迭代page范围内的newList属性 --> <s:iterator status="st" value="#attr.newList"> <tr <s:if test="#st.odd"> style="background-color:#bbbbbb"</s:if>> <td><s:property/></td> </tr> </s:iterator> </table>
7-7 sort 标签
属性comparator: 实现Comparator的类
source: 集合
public class MyComparator implements Comparator { //决定两个元素大小的方法 public int compare(Object element1, Object element2) { //根据元素字符串长度来决定大小 return element1.toString().length() - element2.toString().length(); } }
<!-- 定义一个Comparator实例 --> <s:bean var="mycomparator" name="org.crazyit.app.util.MyComparator"/> <!-- 使用自定义的排序规则对目标集合进行排序 --> <s:sort source="{'疯狂Java讲义' ,'轻量级Java EE企业应用实战' ,'经典Java EE企业应用实战' ,'疯狂Ajax讲义' ,'疯狂XML讲义'}" comparator="#mycomparator" var="sortedList"/> 输出page范围的sortedList属性:<br/> ${pageScope.sortedList} <table border="1" width="300"> <!-- 迭代page范围内的sortedList属性 --> <s:iterator status="st" value="#attr.sortedList"> <tr <s:if test="#st.odd"> style="background-color:#bbbbbb"</s:if>> <td><s:property/></td> </tr> </s:iterator> </table>
8 数据标签
8-1 action 标签
属性id:可选属性,该属性将会作为该Action的引用ID
name:必填属性,指定该标签调用哪个Action
namespace:可选,指定该标签调用的Action所在的namespace.
executeResult:可选,指定是否要将Action的处理结果页面包含到本页面。默认是false,即不包含。
ignoreContextParams:可选,它指定该页面中的请求参数是否需要传入调用的Action、默认是false,即将本页的请求参数传入被调用的Action。
使用s:action标签在页面中调用Action
public class TagAction extends ActionSupport { //封装用户请求参数的author属性 private String author; //author属性的setter和getter方法 public void setAuthor(String author) { this.author = author; } public String getAuthor() { return this.author; } //定义第一个处理逻辑 public String execute() throws Exception { return "done"; } //定义第二个处理逻辑 public String login() throws Exception { ActionContext.getContext(). put("author", getAuthor()); return "done"; } }
struts.xml
<struts> <constant name="struts.custom.i18n.resources" value="mess"/> <constant name="struts.i18n.encoding" value="GBK"/> <package name="lee" extends="struts-default"> <!-- 定义第一个Action,使用TagAction的 execute方法作为控制处理逻辑 --> <action name="tag1" class="org.crazyit.app.action.TagAction"> <result name="done">succ.jsp</result> </action> <!-- 定义第二个Action,使用TagAction的 login方法作为控制处理逻辑 --> <action name="tag2" class="org.crazyit.app.action.TagAction" method="login"> <result name="done">loginSucc.jsp</result> </action> <action name=""> <result>.</result> </action> </package> </struts>
下面调用第一个Action,并将结果包含到本页面中。<br/> <s:action name="tag1" executeResult="true"/> <hr/> 下面调用第二个Action,并将结果包含到本页面中。<br/> 但阻止本页面请求参数传入Action。<br/> <s:action name="tag2" executeResult="true" ignoreContextParams="true"/> <hr/> 下面调用第三个Action,且并不将结果包含到本页面中。<br/> <s:action name="tag2" executeResult="false"/> 本页面是否可访问?<s:property value="author"/>
8-2 bean 标签
属性name:必选属性,指定要实例化的 JavaBean 的实现类。
var:可选属性,如果指定该属性,则该 JavaBean 实例会被放入 Stack Context 中,并放入 requestScope 中。
使用s:bean标签创建JavaBean的实例
public class Person { private String name; private int age; //name属性的setter和getter方法 public void setName(String name) { this.name = name; } public String getName() { return this.name; } //age属性的setter和getter方法 public void setAge(int age) { this.age = age; } public int getAge() { return this.age; } }
<!-- 使用bean标签创建一个Person类的实例 --> <s:bean name="org.crazyit.app.dto.Person"> <!-- 使用param标签为Person类的实例传入参数 --> <s:param name="name" value="'yeeku'"/> <s:param name="age" value="29"/> <!-- 因为在bean标签内,Person实例位于ValueStack的栈顶, 故可以直接访问lee.Person实例 --> Person实例的name为:<s:property value="name"/><br/> Person实例的age为:<s:property value="age"/> </s:bean>
<!-- 使用bean标签创建一个Person类的实例,为其指定了var属性 --> <s:bean name="org.crazyit.app.dto.Person" var="p"> <!-- 使用param标签为Person类的实例传入参数 --> <s:param name="name" value="'yeeku'"/> <s:param name="age" value="29"/> </s:bean> <!-- 根据JavaBean实例指定的var属性来访问JavaBean实例 --> Person实例的name为:<s:property value="#p.name"/><br/> Person实例的age为:<s:property value="#p.age"/><br/> ${requestScope.p}
8-3 date 标签
属性format: 可选,如指定该属性,将根据该属性指定的格式来格式化日期
nice: 可选,值为true或者false,用于指定是否输出指定日期和当前时刻的时差。默认是false,即不输出
name: 必填,指定要格式化的日期
var: 可选,如果指定了改属性,则该事件对象将被放到ValueStack中,改属性也可以用id来代替,推荐使用var!
使用s:date标签格式化日期
<s:bean var="now" name="java.util.Date"/> nice="false",且指定format="dd/MM/yyyy"<br/> <s:date name="#now" format="dd/MM/yyyy" nice="false"/><hr/> nice="true",且指定format="dd/MM/yyyy"<br/> <s:date name="#now" format="dd/MM/yyyy" nice="true"/><hr/> 指定nice="true"<br/> <s:date name="#now" nice="true" /><hr/> nice="false",且没有指定format属性<br/> <s:date name="#now" nice="false"/><hr/> nice="false",没有指定format属性,指定了var<br/> <s:date name="#now" nice="false" var="abc"/><hr/> ${requestScope.abc} <s:property value="#abc"/>
#国际化资源文件中指定 struts 2 默认的时间格式 struts.date.format=yyyy年MM月dd日
8-4 debug 标签
debug 标签主要用于调试,它在页面上生成一个超级链接,通过该链接可以查看到 ValueStack 和 Stack Context 中所有的值信息。<s:debug />
8-5 include 标签
使用s:include标签来包含目标页面,包括 JSP 页面和 Servlet 。此外,可以为 标签添加<!-- 使用include标签来包含其他页面 --> <s:include value="included-file.jsp"/> <!-- 使用include标签来包含其他页面,并且传入参数 --> <s:include value="included-file.jsp"> <s:param name="author" value="'yeeku'"/> </s:include>
<h3>被包含的页面</h3> author参数值为:${param.author}
8-6 param 标签
<param name="color">blue</param>
或
<param name="color" value="blue" />
如果为字符串
<param name="color" value="'blue'" />
8-7 push 标签
Push标签是将值存在值栈中,在设置push标签时应将标签放在使用属性之前。<!-- 使用bean标签创建一个JavaBean实例, 指定var属性,并将其放入Stack Context中 --> <s:bean name="org.crazyit.app.dto.Person" var="p"> <s:param name="name" value="'yeeku'"/> <s:param name="age" value="29"/> </s:bean> <!-- 将Stack Context中的p对象放入ValueStack栈顶--> <s:push value="#p"> <!-- 输出ValueStack栈顶对象的name和age属性 --> ValueStack栈顶对象的name属性:<s:property value="name"/><br/> ValueStack栈顶对象的age属性:<s:property value="age"/><br/> </s:push>
只有在 push 标签内时,被 push 标签放入 ValueStack 中的对象才存在;一旦离开了 push 标签,则刚刚被放入的元素将立即被移出 ValueStack 。
8-8 set 标签
使用s:set设置一个新变量<!-- 使用bean标签定义一个JavaBean实例 --> <s:bean name="org.crazyit.app.dto.Person" id="p"> <s:param name="name" value="'yeeku'"/> <s:param name="age" value="29"/> </s:bean> 将Stack Context中的p值放入默认范围(action)内。<br/> <s:set value="#p" name="xxx"/> Stack Context内xxx对象的name属性:<s:property value="#xxx.name"/><br/> Stack Context内xxx对象的age属性:<s:property value="#xxx.age"/><br/> request范围的xxx对象的name属性:${requestScope.xxx.name}<br/> request范围的xxx对象的age属性:${requestScope.xxx.age}<hr/> 将Stack Context中的p值放入application范围内。<br/> <s:set value="#p" name="yyy" scope="application"/> application范围的yyy对象的name属性:${applicationScope.yyy.name}<br/> application范围的yyy对象的age属性:${applicationScope.yyy.age}<hr/> 将Stack Context中的p值放入session范围内。<br/> <s:set value="#p" name="zzz" scope="session"/> session范围的zzz对象的name属性:${sessionScope.zzz.name}<br/> session范围的zzz对象的age属性:${sessionScope.zzz.age}
8-9 url 标签
属性s:url来生成一个URL地址
只指定value属性的形式。<br/> <s:url value="editGadget.action"/> <hr/> 指定action属性,且使用param传入参数的形式。<br/> <s:url action="showBook"> <s:param name="author" value="'yeeku'" /> </s:url> <hr/> 既不指定action属性,也不指定value属性,且使用param传入参数的形式。<br/> <s:url includeParams="get" > <s:param name="id" value="%{'22'}"/> </s:url> <hr/> 同时指定action属性和value属性,且使用param传入参数的形式。<br/> <s:url action="showBook" value="xxxx"> <s:param name="author" value="'yeeku'" /> </s:url>
8-10 property 标签
9 主题与模板
Struts 2 所有的UI标签都是基于主题和模板的,主题和模板是 Struts 2 所有 UI 标签的核心。设定主题的方法:
前面的优先级高。
模板目录是存放所有模板文件的地方,所有的模板文件以主题的方式来组织,模板目录下有图示目录结构:
struts 2 默认提供了三个主题
simple:最简单的主题,最底层的结构,主要用于构建 HTML UI 组件。
xhtml:struts 2 默认的主题。
css_xhtml:在 xhtml 主题基础上加入了 CSS 样式控制。
从 struts 2.1 开始, struts 2 核心包不再提供 Ajax 主题,而是由 struts2-dojo-plugin-2.2.1.jar 来提供 Ajax 主题。
10 自定义主题
10-1 开发者完全实现一个全新的主题
需要很大工作量,一般不推荐。10-2 包装一个现有的主题
10-3 扩展一个现有的主题
<#include "/${parameters.templateDir}/xhtml/controlheader.ftl" /> <#include "/${parameters.templateDir}/simple/select.ftl" /> <#include "/${parameters.templateDir}/xhtml/controlfooter.ftl" />
parent=xhtml
<s:select name="aa" theme="lee" list="{'hhh', 'fff', 'ggg'}" size="5" />
11 表单标签
所有表单标签处理类都继承了 UIBean 类,UIBean 包含了一些通用属性,模板相关属性
Javascript 相关通用属性
与 Tooltip 相关的通用属性
11-1 表单标签的 name 和 value 属性
<!-- 将下面文本框的值绑定到 Action 的 person 属性的 firstName 属性 --> <s:textfield name="person.firstName" />
11-2 checkboxlist 标签
属性使用s:checkboxlist生成多个复选框
<s:form> <!-- 使用简单集合来生成多个复选框 --> <s:checkboxlist name="a" label="请选择您喜欢的图书" labelposition="top" list="{'轻量级Java EE企业应用实战' , '经典Java EE企业应用实战' , '疯狂Java讲义'}"/> <!-- 使用简单Map对象来生成多个复选框 使用Map对象的key(书名)作为复选框的value, 使用Map对象的value(出版时间)作为复选框的标签--> <s:checkboxlist name="b" label="请选择您想选择出版日期" labelposition="top" list="#{'疯狂Java讲义':'2008年9月' ,'轻量级Java EE企业应用实战':'2008月12月' ,'经典Java EE企业应用实战':'2010年8月'}" listKey="key" listValue="value"/> <!-- 创建一个JavaBean对象,并将其放入Stack Context中 --> <s:bean name="org.crazyit.app.service.BookService" id="bs"/> <!-- 使用集合里放多个JavaBean实例来生成多个复选框 使用集合元素里name属性作为复选框的标签 使用集合元素里author属性作为复选框的value--> <s:checkboxlist name="b" label="请选择您喜欢的图书" labelposition="top" list="#bs.books" listKey="author" listValue="name"/> </s:form>
public class BookService { public Book[] getBooks() { return new Book[] { new Book("疯狂Java讲义","李刚"), new Book("轻量级Java EE企业应用实战","李刚"), new Book("经典Java EE企业应用实战","李刚"), new Book("疯狂Ajax讲义","李刚") }; } }
public class Book { private String name; private String author; //无参数的构造器 public Book() { } //初始化全部属性的构造器 public Book(String name , String author) { this.name = name; this.author = author; } //name属性的setter和getter方法 public void setName(String name) { this.name = name; } public String getName() { return this.name; } //author属性的setter和getter方法 public void setAuthor(String author) { this.author = author; } public String getAuthor() { return this.author; } }
11-3 doubleselect 标签
使用s:doubleselect生成级联下拉列表框<s:form action="x"> <s:doubleselect label="请选择您喜欢的图书" name="author" list="{'李刚', 'David'}" doubleList="top == '李刚' ? {'轻量级Java EE企业应用实战', '经典Java EE企业应用实战','疯狂Java讲义'}: {'JavaScript: The Definitive Guide'}" doubleName="book"/> </s:form>
默认情况下,第一个下拉列表框只支持两项,如果第一个下拉列表要包含三项或以上,可以这样实现:
首先定义一个 map 对象,该 map 对象的 value 都是集合,这样就能以 map 对象的多个 key 创建第一个下拉列表框的列表项,而每个 key 对应的集合则用于创建第二个下拉列表框的列表项:
<!-- 创建一个复杂的Map对象,key为普通字符串,value为集合 --> <s:set name="bs" value="#{'李刚': {'疯狂Java讲义', '轻量级Java EE企业应用实战','经典Java EE企业应用实战'}, 'David': {'JavaScript: The Definitive Guide'}, 'Johnson': {'Expert One-on-One J2EE Design and Development'}}"/> <!-- 使用Map对象来生成级联列表框 --> <s:form action="x"> <s:doubleselect label="请选择您喜欢的图书" size="3" name="author" list="#bs.keySet()" doubleList="#bs[top]" doubleSize="3" doubleName="book"/> </s:form>
11-4 head 标签
11-5 optiontransferselect 标签
<s:form> <!-- 使用简单集合对象来生成可移动的下拉列表框 --> <s:optiontransferselect label="请选择你喜欢的图书" name="cnbook" leftTitle="中文图书:" rightTitle="外文图书" list="{'疯狂Java讲义' ,'Struts 2权威指南', '轻量级Java EE企业应用实战','经典Java EE企业应用实战'}" multiple="true" addToLeftLabel="向左移动" selectAllLabel="全部选择" addAllToRightLabel="全部右移" headerKey="cnKey" headerValue="--- 选择中文图书 ---" emptyOption="true" doubleList="{'Expert One-on-One J2EE Design and Development', 'JavaScript: The Definitive Guide'}" doubleName="enBook" doubleHeaderKey="enKey" doubleHeaderValue="--- 选择外文图书 ---" doubleEmptyOption="true" doubleMultiple="true" /> </s:form>
11-6 select 标签
<s:form> <!-- 使用简单集合来生成下拉选择框 --> <s:select name="a" label="请选择您喜欢的图书" labelposition="top" multiple="true" list="{'疯狂Java讲义','轻量级Java EE企业应用实战', 'JavaScript: The Definitive Guide'}"/> <!-- 使用简单Map对象来生成下拉选择框 --> <s:select name="b" label="请选择您想选择出版日期" labelposition="top" list="#{'疯狂Java讲义':'2008年9月', '轻量级Java EE企业应用实战':'2008月12月', '经典Java EE企业应用实战':'2010年7月'}" listKey="key" listValue="value"/> <!-- 创建一个JavaBean实例 --> <s:bean name="org.crazyit.app.service.BookService" id="bs"/> <!-- 使用集合里放多个JavaBean实例来生成下拉选择框 --> <s:select name="c" label="请选择您喜欢的图书" labelposition="top" multiple="true" list="#bs.books" listKey="author" listValue="name"/> </s:form>
11-7 radio 标签
<s:form> <!-- 使用简单集合来生成多个单选框 --> <s:radio name="a" label="请选择您喜欢的图书" labelposition="top" list="{'疯狂Java讲义','轻量级Java EE企业应用实战', '经典Java EE企业应用实战'}"/> <!-- 使用简单Map对象来生成多个单选框 --> <s:radio name="b" label="请选择您想选择出版日期" labelposition="top" list="#{'疯狂Java讲义':'2008年9月' ,'轻量级Java EE企业应用实战':'2008月12月' ,'经典Java EE企业应用实战':'2010年8月'}" listKey="key" listValue="value"/> <!-- 创建一个JavaBean实例 --> <s:bean name="org.crazyit.app.service.BookService" id="bs"/> <!-- 使用集合里放多个JavaBean实例来生成多个单选框 --> <s:radio name="c" label="请选择您喜欢的图书" labelposition="top" list="#bs.books" listKey="author" listValue="name"/> </s:form>
11-8 optgroup 标签
必须放在<s:form> <!-- 直接使用Map为列表框生成选项 --> <s:select label="选择您喜欢的图书" name="book" size="7" list="#{'疯狂Java讲义':'李刚' ,'轻量级Java EE企业应用实战':'李刚' ,'经典Java EE企业应用实战':'李刚'}" listKey="value" listValue="key"> <!-- 使用Map对象来生成选择框的选项组 --> <s:optgroup label="Rod Johnson" list="#{'Expert One-on-One J2EE Design and Development':'Johnson'}" listKey="value" listValue="key"/> <s:optgroup label="David Flanagan" list="#{'JavaScript: The Definitive Guide':'David'}" listKey="value" listValue="key"/> </s:select> </s:form>
11-9 token 标签
防止多次提交表单的标签。<s:form action="pro"> <!-- 普通表单域 --> <s:textfield name="book" key="book"/> <!-- 用于防刷新的token --> <s:token/> <s:submit value="提交"/> </s:form>
如果要该标签起作用,则应该在 struts 2 的配置文件中启用 TokenInterceptor 拦截器或 TokenSessionStoreInterceptor 拦截器。
<struts> <constant name="struts.custom.i18n.resources" value="mess"/> <constant name="struts.i18n.encoding" value="GBK"/> <package name="lee" extends="struts-default"> <!-- 定义名为pro的Action,其实现类为lee.ProAction --> <action name="pro" class="org.crazyit.app.action.ProAction"> <!-- 使用系统默认的拦截器栈 --> <interceptor-ref name="defaultStack"/> <!-- 使用防刷新的token拦截器 --> <interceptor-ref name="token"/> <!-- 定义重复提交转向的视图,该逻辑视图名必须是invalid.token --> <result name="invalid.token">/refresh.jsp</result> <!-- 如果处理结果返回success,对应/show.jsp视图资源 --> <result name="success">/show.jsp</result> </action> <action name=""> <result>.</result> </action> </package> </struts>
11-10 updownselect 标签
<s:form> <!-- 使用简单集合来生成可上下移动选项的下拉选择框 --> <s:updownselect name="a" label="请选择您喜欢的图书" labelposition="top" moveUpLabel="向上移动" list="{'疯狂Java讲义' , '轻量级Java EE企业应用实战' , '经典Java EE企业应用实战'}"/> <!-- 使用简单Map对象来生成可上下移动选项的下拉选择框 且使用emptyOption="true"增加一个空选项--> <s:updownselect name="b" label="请选择您想选择出版日期" labelposition="top" moveDownLabel="向下移动" list="#{'疯狂Java讲义':'2008年9月' ,'轻量级Java EE企业应用实战':'2008月12月' ,'经典Java EE企业应用实战':'2010年6月'}" listKey="key" emptyOption="true" listValue="value"/> <s:bean name="org.crazyit.app.service.BookService" id="bs"/> <!-- 使用集合里放多个JavaBean实例来可上下移动选项的生成下拉选择框 --> <s:updownselect name="c" label="请选择您喜欢的图书的作者" labelposition="top" selectAllLabel="全部选择" multiple="true" list="#bs.books" listKey="author" listValue="name"/> </s:form>
12 非表单标签
actionerroractionmessage
component
fielderror
12-1 actionerror 和 actionmessage 标签
public class DemoAction extends ActionSupport { public String execute() { //添加两条Error信息 addActionError("第一条错误消息!"); addActionError("第二条错误消息!"); //添加两条普通信息 addActionMessage("第一条普通消息!"); addActionMessage("第二条普通消息!"); return SUCCESS; } }
<s:actionerror/> <s:actionmessage />
<s:action name="demo" executeResult="true" />
12-2 component 标签
常常需要指定如下三个属性:theme:自定义组件所使用的主题,如果不指定该属性,默认使用xhtml主题。
templateDir:指定自定义组件的主题目录,如果不指定,默认使用系统的主题目录,即template目录。
template:指定自定义组件所使用的模板。
此外,还可以在 component 标签内使用 param 子标签,向该标签模板传入额外的参数。
使用s:component标签
使用默认主题(xhtml),默认主题目录(template)<br/> 使用mytemplate.jsp作为视图组件 <s:component template="mytemplate.jsp"> <s:param name="list" value="{'疯狂Java讲义' ,'轻量级Java EE企业应用实战' ,'经典Java EE企业应用实战'}"/> </s:component> <hr/> 使用自定义主题,自定义主题目录<br/> 使用myAnotherTemplate.jsp作为视图组件 <s:component templateDir="myTemplateDir" theme="myTheme" template="myAnotherTemplate.jsp"> <s:param name="list" value="{'疯狂Java讲义' ,'轻量级Java EE企业应用实战' ,'经典Java EE企业应用实战'}" /> </s:component>
<%@ page contentType="text/html; charset=GBK" language="java"%> <%@taglib prefix="s" uri="/struts-tags" %> <div style="background-color:#eeeeee;"> <b>JSP自定义模板<br/> 请选择您喜欢的图书<br/></b> <s:select list="parameters.list"/> </div>
<%@ page contentType="text/html; charset=GBK" language="java"%> <%@taglib prefix="s" uri="/struts-tags" %> <div style="background-color:#bbbbbb;"> JSP自定义模板<br/> 请选择您喜欢的图书<br/> <select> <s:iterator value="%{top.parameters.list}"> <option><s:property/></option> </s:iterator> </select> </div>
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- 一个jar包里的网站