Struts2学习笔记(三)
一、Struts2国际化
Struts2可以为JSP页面、Action、全局范围分别提供不同的国际化资源,这样维护系统时可以分开维护JSP页面、Action的国际化资源,从而提供更好的可维护性。Struts2国际化的步骤与Java国际化的步骤基本相似,Struts2的国际化可按如下步骤进行:
- 让系统加载国际化资源,加载国际化资源文件有两种方式。
- 自动加载:Action范围的国际化资源文件、包范围的国际化资源文件由系统自动加载
- 手动加载:JSP范围的国际化资源、全局范围的国际化资源文件,分别使用标签、配置常量的方式来手动加载
- 输出国际化,Struts2输出国际化消息同样有两种方式。
- 在视图页面上输出国际化消息,需要使用Struts2的标签库
- 在Action类中输出国际化消息,需要使用ActionSupport的getText()方法来完成
- 中国:zh
- 英语:en
- 法语:fr
- 德语:de
- 日语:ja
- 俄语:ru
- 中国:CN
- 英国:GB
- 法国:FR
- 德国:DE
- 香港:HK
- *:TW
- 日本:JP
1.1 视图页面的国际化
在JSP页面中指定国际化资源需要借助于Struts2的标签:<s:il8n..>
如果把<s:il8n..>作为父标签,则其包含的所有Struts2标签都会加载<s:il8n..>内指定的国际化资源文件,使用name属性指定国际化资源文件的限定名。当然我们可以用该标签包在<html>的外面,这样整个页面的显示内容都可以使用配置好的国际化资源文件。
稍后完善——》》》
二、Struts2标签库
2.1 Struts2标签库概述
Struts2标签库的标签不依赖于任何表现层技术,Struts2把所有的标签都定义在一个s标签库里。Struts2把所有的标签都定义在URI为“/struts-tags”空间下,但依然可以对Struts2标签进行简单的分类。Struts2可以将所有标签分为三大类:
- UI(User Interface,用户界面)标签:主要用于生成HTML元素的标签
- 表单标签:主要用于生成HTML页面的form元素,以及普通表单元素的标签
- 非表单标签:主要用于生成页面上的树、Tab页等标签
- 非UI标签:主要用于数据访问、逻辑控制等的标签
- 流程控制标签:主要包含用于实现分支、循环等流程控制的标签
- 数据访问标签:主要包含用于输出ValueStack中的值、完成国际化等功能的标签
- Ajax标签:用于Ajax(Asynchronous JavaScript And XML)支持的标签
- <%@ taglib prefix="s" uri="/struts-tags"%>
2.2 Struts2的OGNL表达式语言
OGNL表达式语言与JSP 2 EL的作用完全相似,而OGNL并不是真正的编程语言,只是一种数据访问语言。OGNL是Apache开源项目的子项目,其所需要的依赖包包括:ognl-*.jar和javassist-*.GA.jar。OGNL充斥在Struts2前后台数据传递与存储的方方面面,给Struts2中数据的处理带来了极大的方便。2.2.1 OGNL基础
OGNL(Object-Graph Navigation Language的简称),对象图导航语言,它是一门表达式语言,除了用来设置和获取Java对象的属性之外,另外提供诸如集合的投影和过滤以及lambda表达式等。
Ognl中,常用到的两个类:
- ognl.Ognl类:这个类主要用来解析和解释执行Ognl表达式
- ognl.OgnlContext类:这个类为Ognl表达式提供了一个执行环境
OgnlContext类实现了Map接口,所以允许通过put(key,obj)方法向OgnlContext环境中方式各种类型的对象。
需要注意的是在OgnlContext中对象分为两种:
- 第一种是叫做root对象(根对象),在整个OgnlContext中有且最多只能有一个根对象,可以通过调用OgnlContext.setRoot(obj)设置为根对象。
- 第二种就是OgnlContext中的普通对象,这种个数类型不受限制。
如果需要访问的属性属于根对象,则可以直接访问该属性;否则必须使用一个对象名作为前缀修饰该属性,并且在最前面用#修饰。其原理是这样的,如果Ognl在解析表达式的时候发现表达式开头带有"#",会去普通对象中去寻找,如果没有"#",则会默认去根对象中去寻找,由于根对象只有一个,所以只需要属性名字即可。
示例:
dept对象就是放置到OgnlContext中的普通对象,对于这种普通对象,只能通过“#dept.name”的方式去获取属性值,需要注意的是dept指的是放置到上下文中key的值,另外在Dept类型中要提供getName方法。
Ognl中的过滤和投影:
- 过滤与投影都是针对于数组、集合和Map而言的
- 过滤指的是将原集合中不符合条件的对象过滤掉,然后将满足条件的对象,构建一个新的集合对象返回,Ognl过滤表达式的写法是:collection.{?|^|$ expression}
- 投影指的是将原集合中所有对象的某个属性抽取出来,单独构成一个新的集合对象返回,基础语法为 :collection.{expression}
- OGNL表达式需要放置到OgnlContext中才能得到正确地解析、解释和执行
- OgnlContext类实现了Map接口,所以可以使用put方法向里面放置元素且每个OgnlContext有且最多只能有一个根对象
- Ognl表达式中访问根对象的属性时,无需"#",普通对象则需要
2.2.2 Struts2中OGNL基础
Struts2使用标准的Context来进行OGNL表达式语言求值,OGNL的*对象是Stack Context(有时也称为OGNL Context),Stack Context对象就是一个Map类型的实例,其根对象就是ValueStack,而ValueStack是Stack Context内的根对象,如果需要访问ValueStack里的属性,直接通过如下方式即可:${属性名}
Struts2还提供了一些命名对象,但这些命名对象都不是根对象,只是存在于Stack Context中。所以访问这些对象时需要使用#前缀来指明:
- parameters对象:用于访问HTTP请求参数。例如#parameters['foo]或#parameters.foo,用于返回调用HttpServletRequest的getParameter("foo")方法的返回值
- request对象:用于访问HttpServletRequest的属性。例如#request['foo']或#request.foo,用于返回调用HttpServletRequest的getAttribute(“foo”)方法的返回值
- session对象:用于访问HttpSession的属性。
- application对象:用于访问ServletContext的属性。
- attr对象:该对象将一次搜索如下对象:PageContext、HttpServletRequest、HttpSession、ServletContext中的属性
- 访问Stack Context里的命名对象需要在对象名之前添加#前缀
- 当访问OGNL的Stack Context里“根”对象的属性时,可以省略对象名
2.2.3 OGNL中的集合操作
很多时候,可能需要一个集合对象(例如List对象,或者Map对象),使用OGNL表达式可以直接创建集合对象。
- 创建List类型集合的语法为:{e1,e2,e3...}
- 创建Map类型集合的语法为:#{key1:value1,key2:value2...}
对于集合,OGNL提供了两个运算符:in和not in,其中in判断某个元素是否在指定集合中;not in则用来判断某个元素是否不在指定集合中。
OGNL还允许通过某个规则取得集合的子集,取得子集时有如下三个操作符:
- ?:去除所有符合选择逻辑的元素
- ^:取出符合选择逻辑的第一个元素
- $:取出符合选择逻辑的最后一个元素
2.2.4 访问静态成员
OGNL表达式还提供了一种访问静态成员(包括调用静态方法、访问静态成员变量)的方式,但Struts2默认关闭了访问静态方法,只允许通过OGNL表达式访问静态Field。为了让OGNL表达式可以访问静态方法,应该在Struts2应用中将struts.ognl.allowStaticMethodAccess设置为true,配置如下:
- <!-- 设置允许通过OGNL访问静态方法 -->
- <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
一旦设置了上面所示常量,OGNL表达式可以通过如下语法来访问静态成员:
- @[email protected]
- @[email protected](val...)
2.2.5 Lambda表达式
暂不理解——》》》
2.3 控制标签
Struts2的非UI标签包括控制标签和数据标签,主要用于完成流程控制,以及操作Struts2的ValueStack。数据标签主要结合OGNL表达式进行数据访问。控制标签包含如下9个标签:- if:用于控制选择输出的标签
- elseIf/elseif:与if标签结合使用,用于控制选择输出的标签
- else:与if标签结合使用,用于控制选择输出的标签
- append:用于将多个集合拼接成一个新的集合
- generator:它是一个字符串解析器,用于将一个字符串解析成一个集合
- iterator:这是一个迭代器,用于将集合迭代输出
- merge:用于将多个集合拼接成一个新的集合。丹玉append的拼接方式有所不同
- sort:这个标签用于对集合进行排序
- subset:这个标签用于截取集合的部分元素,形成一个新的子集合
2.3.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>
2.3.2 iterator标签
iterator标签主要用于对集合进行迭代,这里的集合包含List、Set和数组,也可对Map集合进行迭代输出。使用<s:iterator.../>标签对集合进行迭代输出时,可以指定如下三个属性:- value:可选属性,用于指定被迭代的集合,该集合通常使用OGNL表达式指定。如果没有指定,则会默认使用ValueStack栈顶的集合
- id:可选属性,指定集合里元素的ID
- status:可选属性,该属性指定迭代时的IteratorStatus实例,通过该实例即可判断当前迭代元素的属性。例如是否为最后一个,以及当前迭代元素的索引等
- int getCount():返回当前迭代了几个元素
- int getIndex():返回当前迭代元素的索引
- boolean isEven():返回当前被迭代元素的索引是否是偶数
- boolean isOdd:返回当前被迭代元素的索引是否是奇数
- boolean isFirst:返回当前被迭代元素是否是第一个元素
- boolean isLast:返回当前被迭代元素是否是最后一个元素
- <!-- 对指定的Map对象进行迭代输出,并指定status属性 -->
- <s:iterator value="#{'疯狂Java讲义':'李刚',
- '轻量级Java EE企业应用实战':'李刚' ,
- '疯狂iOS讲义':'李刚'}"
- 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>
2.3.3 append标签
append标签用于将多个集合对象拼接起来,组成一个新的集合,通过这种拼接,从而允许通过一个<s:iterator>标签就完成对多个集合的迭代。
通过该标签的var属性来指定新集合的名字,而该标签下可以有多个<s:param..>子标签,每个子标签指定一个集合。而新集合被放入到Stack Context中。
示例如下:
- <!-- 使用append将List和Map集合拼接在一起
- 新集合实际上是Map集合,其名字为newList -->
- <s:append var="newList">
- <s:param
- value="#{'疯狂Java讲义':'李刚','疯狂iOS讲义':'李刚','经典Java EE企业应用实战':'李刚'}" />
- <s:param value="#{'http://www.crazyit.org','http://www.fkit.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>
2.3.4 generator标签
使用generator标签可以将指定字符串按指定分隔符分隔成多个子串,临时生成的多个子串可以使用Iterator标签来迭代输出。注:在该标签的标签体内,整个临时生成的集合将位于ValueStack的顶端,但一旦该标签结束,该集合将被移除ValueStack。 使用generator标签时可以指定如下几个属性:
- count:可选属性,该属性是一个可选的属性,该属性指定生成集合中元素的总数
- separator:必填属性,该属性指定用于解析字符串的分隔符
- val:必填属性,该属性指定被解析的字符串
- converter:可选属性,该属性指定要给转化器,该转换器负责将集合中的每个字符串转换成对象,通过该转换器可以将一个字符串解析成对象集合。注:该属性值必须是一个org.apache.Struts2.util.IteratorGenerator.Converter对象
- var:可选属性,将生成的Iterator对象翻入Stack Context中。
注意:Struts2的很多标签都与该标签类似,他们都可以指定var属性,一旦指定了var属性(相当于有了句柄),则会将新生成、新设置的值放入StackContext中(必须通过#name形式访问);如果不指定var属性,则没有可以操作的句柄也就没有意义了,而且Struts处理方式是在该标签内,新生成、新设置的值有效,可以是一旦该标签结束就会被清除,也可以看做是一个局部变量吧。
2.3.5 merge标签
merge标签与append标签作用一样都是将多个集合拼接成一个集合,使用方法也类同,只是它们采用的方法不同而已。
- append拼接的方式是将多个集合简单的首尾相连
- merge拼接的方式是每个集合中选取最前面的一个元素连接,然后循环持续下去,直至原集合中没有元素为止
2.3.6 subset标签
subset标签用于取得集合的子集,该标签的底层通过org.apache.struts2.util.SubsetIteratorFilter类提供实现,该标签包含如下几个属性:
- count:可选属性,指定子集中元素的个数,默认为取得源集合的全部元素
- source:可选属性,指定源集合,如果不指定,则默认取得ValueStack栈顶的集合
- start:可选属性,该属性指定子集从源集合的第几个元素开始截取。默认从第一个元素(即start的默认值为0)开始截取
- decider:可选属性,指定有开发者自己决定是否选中该元素。该属性必须指定一个org.apache.struts2.util.SubsetIteratorFilter.Decider对象
- var:可选属性,如果指定了该属性,则将生成的Iterator对象设置成page范围的属性
下面以自定义的截取标准为例:
- // 用户自定义的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讲义'
- ,'疯狂iOS讲义'}"
- 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>
2.3.7 sort标签
sort标签用于对栈顶的集合元素进行排序,但前提必须我们自己定义排序规则,即实现自己的Comparator,自己的Comparator需要实现java.util.Comparator接口。sort标签包含如下几个标签:- comparator:必填属性,该属性指定进行排序的Comparator实例
- source:可选属性,指定被排序的集合,默认情况下对ValueStack栈顶的集合进行排序
- var:可选属性,,如果指定了该属性,则将生成的Iterator对象设置成page范围的属性,不放入ValueStack中
- public class MyComparator implements Comparator<Object> {
- // 决定两个元素大小的方法
- 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讲义'
- ,'疯狂iOS讲义'}"
- 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>
注:sort标签的var属性只是将排序后也只是将排序后的新集合放入pageScope中,并未放入OGNL的StackContext中。
2.4 数据标签
数据标签主要用于提供各种数据访问的功能,包含显示一个Action里的属性,以及生成国际化输出等功能。数据标签主要包含如下几个:- action:该标签用于在JSP页面直接调用一个Action,通过指定executeResult参数,还可将该Action的处理结果包含到本页面中来
- bean:该标签用于创建一个JavaBean实例。如果指定了var属性,则可以将创建的JavaBean实例放入StackContext中
- date:用于格式化输出一个日期
- debug:用于在页面上生成一个调试连接,当单机该链接时,可以看到当前ValueStack和StackContext中的内容
- il8n:用于指定国际化资源文件的baseName
- include:用于在JSP页面中包含其他的JSP或Servlet资源
- param:用于设置一个参数,通常是用作bean标签、url标签的子标签
- push:用于将某个值放入ValueStack的栈顶
- set:用于设置一个新变量,并可以将新变量放入指定的范围内
- text:用于输出国际化信息
- url:用于生成一个URL地址
- property:用于输出某个值,包括输出ValueStack、StackContext和ActionContext中的值
2.4.1 action标签
使用action标签可以允许在JSP页面中直接调用Action,因为需要调用Action,所以可以指定需要被调用Action的name及namespace。如果指定了executeResult参数的属性值为true,该标签还会把Action 的处理结果(视图资源)包含到本页面来(与include功能类同)。action标签包含如下几个属性:
- var:可选属性,一旦定义了该属性,该Action将被放入StackContext中
- name:必填属性,该属性指定该标签调用哪个Action
- namespace:可选属性,该属性指定该标签调用的Action所在的namespace
- executeResult:可选属性,该属性指定是否要将Action的处理结果页面包含到本页面,默认值为false,即不包括
- ignoreContextParams:可选参数,指定该页面中的请求参数是否需要传入调用的Action,默认值为false,即将本页面的请求参数传入被调用的Action
2.4.2 bean标签
- name:必填属性,该属性指定要实例化的JavaBean的实现类
- var:可选属性,指定该属性,则该JavaBean实例会被放入StackContext中,并放入requestScope中
- <!-- 使用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}
2.4.3 date标签
- format:可选属性,如果指定了该属性,将根据该属性指定的格式来格式化日期
- nice:可选属性,该属性只能为true或false,它用于指定是否输出指定日期和当前时刻之间的时间差。默认值为false,即表示不输出时间差
- name:必填属性,指定要格式化的日期值
- var:可选属性,指定该属性,格式化后的字符串将被放入StackContext中并放入requestScope中,但不会在页面上输出
- <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"/>
- </body>
2.4.4 debug标签
debug标签主要用于辅助调试,他在页面上创建一个超链接,通过该链接可以查看到ValueStack和StackContext中的所有值信息。
2.4.5 include标签
include标签用于将一个JSP页面,或者一个Servlet包含到本页面中。该标签包含如下属性:
- value:必填属性,指定需要包含的JSP页面,或者Servlet
2.4.6 param标签
param标签主要用于为其他标签提供参数,param标签包含如下属性:
- name:可选属性,指定需要设置参数的参数名
- value:可选属性,指定需要设置参数的参数值
- <param name="color">blue</param>
- <param name="color" value="blue"/>
- <param name="color" value="'blue'"/>
2.4.7 push标签
push标签用于将某个值放到ValueStack的栈顶,从而可以更简单地访问该值,该标签包含如下属性:- value:必填属性,指定需要放到ValueStack栈顶的值
- <h2>使用s:push来将某个值放入ValueStack的栈顶</h2>
- <!-- 使用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>
2.4.8 set标签
- scope:可选属性,指定新变量被放置的范围,该属性可以接受application、session、request、page或action这5个值,默认值为action。(指定action范围,则该值被放入request范围中,冰杯放入到OGNL的StackContext中)
- value:可选属性,指定将赋给变量的值。如果没有指定,则将ValueStack栈顶的值赋给新变量
- var:可选属性,如果指定该值,则该值将会被放入ValueStack中
- <h2>使用s:set设置一个新变量</h2>
- <!-- 使用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}
2.4.9 url标签
- action:可选属性,指定生成URL地址为哪个Action,如果Action不提供,就使用value作为URL的地址值
- value:可选属性,指定生成URL的地址值,如果value不提供就用action属性指定的Action作为URL地址
- anchor:可选属性,指定URL的锚点
- encode:可选属性,指定是否需要对参数进行编码,默认是true
- escapeAmp:可选参数,指定是否需要对&符号进行编码,默认是true
- forceAddSchemeHostAndPort:可选参数,指定是否需要在URL对应的地址里强制添加scheme、主机和端口
- includeContext:可选属性,指定是否需要将当前上下文包含在URL地址中
- includeParams:可选属性,指定是否包含请求参数,该属性的属性值只能为none、get或者all,默认是get
- method:可选属性,指定Action的方法,当使用Action来生成URL时,如果指定了该属性,则URL将链接到指定Action的特定方法
- namespace:可选属性,该属性指定命名空间,当使用Action来生成URL时,如果指定了该属性,则URL将链接到此namespace的指定Action处
- portletMode:可选属性,指定结果页面的portlet模式
- scheme:可选属性,用于设置schema属性
- var:可选属性,如果指定了该属性,将会把该链接值放入Struts2的ValueStack中
- windowState:可选属性,指定结果页面的portlet的窗口状态
- <h2>s:url来生成一个URL地址</h2>
- 只指定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>
2.4.10 property标签
property标签的作用就是输出指定值。property标签输出value属性指定的值,如果没有指定value属性,则默认输出ValueStack栈顶的值。该标签包含如下几个属性:- default:可选属性,如果需要输出的属性值为null,则显示default属性指定的值
- escape:可选属性,指定是否escape HTML代码,默认值为true
- value:可选属性,指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值
2.5 表单标签
- 模板相关属性
- JavaScript相关属性
- 通用属性
- templateDIR:指定该表单所用的模板文件目录
- theme:指定该表单所用的主题
- template:指定该表单所用的模板
- onclick:指定鼠标在该标签生成的表单元素上单击时触发的JavaScript函数
- ondbclic:指定鼠标在该标签生成的表单元素上双击时触发的JavaScript函数
- onmousedown:指定鼠标在该标签生成的表单元素上按下时触发的JavaScript函数
- onmouseup:指定鼠标在该标签生成的表单元素上松开时触发的JavaScript函数
- onmouseover:指定鼠标在该标签生成的表单元素上悬停时触发的JavaScript函数
- onmouseout:指定鼠标移出该标签生成的表单元素时触发的JavaScript函数
- onfocus:指定该标签生成的表单元素得到焦点时触发的函数
- onblur:指定该标签生成的表单元素失去焦点时触发的函数
- onkeypress:指定单击键盘上某个键时触发的函数
- onkeyup:指定松开键盘上某个键时触发的函数
- onkeydown:指定按下键盘上某个键时触发的函数
- onselect:对下拉列表项等可以选择表单元素,指定选中该元素时触发的JavaScript函数
- onchang:对于文本框等可以接受输入的表单元素,指定当值改变时触发的JavaScript函数
- tooltip:设置此组件的Tooltip
- cssClass :设置该表单元素的class属性
- cssStyle:设置该表单元素的style属性,使用内联的CSS样式
- title:设置表单元素的title属性
- disabled:设置表单元素的disaled属性
- lable:设置表单元素的label属性
- labelPosition:设置表单元素的lable所在位置,可接受的值为top(上面)和left(左面),默认是在左边
- requiredposition:定义必填标记(默认以“*”作为必填标记)位于label元素的位置,可接受的值为left(左面)和right(右边),默认为右边
- name:定义表单元素的name属性,该属性值用于与Action属性形成对应
- required:定义是否在表单元素的label上增加必填标记(默认以“*”作为必填标记),这职位true是增加必填标记,否则不增加
- tabIndex:设置表单元素的tabindex属性
- value:设置表单元素的value属性
2.5.1 表单标签的name和value属性
- <!-- 将下面文本框的值绑定到Action的person属性的firstName属性 -->
- <s:textfield name="person.firstName"/>
2.5.2 checkboxlist标签
- listKey:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的value。如果集合是Map,则可以使用key或value值指定Map对象的key或value作为复选框的value。
- listValue:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的标签。如果集合是Map,则可以使用key或value值指定Map对象的key或value作为复选框的标签。
示例如下:
- public class Book {
- private String name;
- private String author;
- // 无参数的构造器
- public Book() {
- }
- // 初始化全部成员变量的构造器
- public Book(String name, String author) {
- this.name = name;
- this.author = author;
- }
- //省略name和author的setter和getter方法
- }
- public class BookService {
- public Book[] getBooks() {
- return new Book[] { new Book("疯狂Java讲义", "李刚"), new Book("轻量级Java EE企业应用实战", "李刚"), new Book("疯狂iOS讲义", "李刚"),
- new Book("疯狂Ajax讲义", "李刚") };
- }
- }
- <h3>使用s:checkboxlist生成多个复选框</h3>
- <s:form>
- <!-- 使用简单集合来生成多个复选框 -->
- <s:checkboxlist name="a" label="请选择您喜欢的图书"
- labelposition="top" list="{'轻量级Java EE企业应用实战'
- , '疯狂iOS讲义'
- , '疯狂Java讲义'}"/>
- <!-- 使用简单Map对象来生成多个复选框
- 使用Map对象的key(书名)作为复选框的value,
- 使用Map对象的value(出版时间)作为复选框的标签-->
- <s:checkboxlist name="b" label="请选择您想选择出版日期"
- labelposition="top" list="#{'疯狂Java讲义':'2008年9月'
- ,'轻量级Java EE企业应用实战':'2008月12月'
- ,'疯狂iOS讲义':'2014年1月'}"
- listKey="key"
- listValue="value"/>
- <!-- 创建一个JavaBean对象,并将其放入Stack Context中 -->
- <s:bean name="org.crazyit.app.service.BookService" var="bs"/>
- <!-- 使用集合里放多个JavaBean实例来生成多个复选框
- 使用集合元素里name属性作为复选框的标签
- 使用集合元素里author属性作为复选框的value-->
- <s:checkboxlist name="b" label="请选择您喜欢的图书"
- labelposition="top"
- list="#bs.books"
- listKey="author"
- listValue="name"/>
- </s:form>
效果图:
2.5.3 radio标签
radio标签的用法与checkboxlist用法几乎完全相同,一样可以指定label、list、listKey和listValue等属性,与checkboxlist唯一不同的是,checkboxlist生成多个复选框,而radio生成多个单选按钮
示例如下:
- <h3>使用s:radio生成多个单选框</h3>
- <s:form>
- <!-- 使用简单集合来生成多个单选框 -->
- <s:radio name="a" label="请选择您喜欢的图书" labelposition="top"
- list="{'疯狂Java讲义','轻量级Java EE企业应用实战',
- '疯狂iOS讲义'}"/>
- <!-- 使用简单Map对象来生成多个单选框 -->
- <s:radio name="b" label="请选择您想选择出版日期" labelposition="top"
- list="#{'疯狂Java讲义':'2008年9月'
- ,'轻量级Java EE企业应用实战':'2008月12月'
- ,'疯狂iOS讲义':'2014年1月'}"
- 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>
效果图:
2.5.4 select标签
select标签用于生成一个下拉列表,使用该标签必须指定list属性,系统会给list属性指定的结合来生成下拉列表框。这个list属性指定的集合,既可以是普通集合,也可以是Map对象,还可以是元素对象的集合。除此之外,select表单还有如下几个常用属性:- listKey:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的value。如果集合是Map,则可以使用key或value值指定Map对象的key或value作为复选框的value。
- listValue:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的标签。如果集合是Map,则可以使用key或value值指定Map对象的key或value作为复选框的标签。
- multiple:设置该列表框是否允许多选
- <h3>使用s:select生成下拉选择框</h3>
- <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月',
- '疯狂iOS讲义':'2014年1月'}"
- 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>
效果图:
2.5.5 optgroup标签
optgroup标签用于生成一个下拉列表框的选项组,因此该标签必须放在<s:select...>标签中使用。一个下拉列表框中可以包含多个选项组,因此可以在一个<s:select...>标签中使用多个<s:optgroup...>标签。该标签一样需要指定list、listKey和listValue等属性,除此之外,使用该标签也可以指定label属性,但这个label属性不是下拉列表框的label,而是该选项组的组名。示例如下:
- <h3>使用s:optgroup生成下拉选择框的选项组</h3>
- <s:form>
- <!-- 直接使用Map为列表框生成选项 -->
- <s:select label="选择您喜欢的图书" name="book" size="7"
- list="#{'疯狂Java讲义':'李刚'
- ,'轻量级Java EE企业应用实战':'李刚'
- ,'疯狂iOS讲义':'李刚'}"
- 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>
效果图:
2.5.6 head标签(暂不理解)
该标签主要用于生成HTML页面的<head...>部分。因为有些主题需要包含特定的CSS和JavaScript代码,而该标签 用于生成对这些CSS和JavaScript代码的引用。
例如,如果需要在页面中使用Ajax组件,则使用一个带theme=“ajax”属性的head标签,就可以将标准的Ajax的头信息包含在页面中。使用Ajax主题时,可以通过设置head标签的debug参数为true,从而打开调试标志。
注:一般使用Struts的UI标签、JavaScript客户端校验等需要JavaScript库和CSS支持功能时,都应该先使用head标签。
2.5.7 updownselect标签
该标签非常类似于select标签,区别是该标签生成的列表框可以上下移动选项。因此使用该标签时,一样可以指定list、listKey和listValue等属性,除此之外,其还支持如下几个属性:
- allowMoveUp:是否显示“上移”按钮,默认是true
- allowMoveDown:是否显示“下移”按钮,默认是true
- allowSelectAll:是否显示“全选”按钮,默认是true
- moveUpLabel:设置“上移”按钮上的文本,默认是∧按钮
- moveDownLabel:设置“下移”按钮上的文本,默认是∨按钮
- selectAllLabel:设置“全选”按钮上的文本,默认是*符号
- <h3>使用s:updownselect生成可上下移动选项的下拉选择框</h3>
- <s:form>
- <!-- 使用简单集合来生成可上下移动选项的下拉选择框 -->
- <s:updownselect name="a" label="请选择您喜欢的图书"
- labelposition="top"
- moveUpLabel="向上移动"
- list="{'疯狂Java讲义'
- , '轻量级Java EE企业应用实战'
- , '疯狂iOS讲义'}"/>
- <!-- 使用简单Map对象来生成可上下移动选项的下拉选择框
- 且使用emptyOption="true"增加一个空选项-->
- <s:updownselect name="b" label="请选择您想选择出版日期"
- labelposition="top"
- moveDownLabel="向下移动"
- list="#{'疯狂Java讲义':'2008年9月'
- ,'轻量级Java EE企业应用实战':'2008月12月'
- ,'疯狂iOS讲义':'2014年1月'}"
- 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>
- list:指定用于输出第一个下拉列表框中选项的集合
- listKey:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的value。如果集合是Map,则可以使用key或value值指定Map对象的key或value作为第一个下拉列表框的value。
- listValue:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的标签。如果集合是Map,则可以使用key或value值指定Map对象的key或value作为作为第一个下拉列表框的标签。
- doubleList:用于输出第二个下拉列表框中选项的集合
- doubleListKey:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的value。如果集合是Map,则可以使用key或value值指定Map对象的key或value作为第二个下拉列表框的value。
- doubleListValue:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的标签。如果集合是Map,则可以使用key或value值指定Map对象的key或value作为作为第二个下拉列表框的标签。
- doubleName:指定第二个下拉列表框的name属性
- <h3>使用s:doubleselect生成级联下拉列表框</h3>
- <s:form action="x">
- <s:doubleselect
- label="请选择您喜欢的图书"
- name="author" list="{'李刚', 'David'}"
- doubleList="top == '李刚' ? {'轻量级Java EE企业应用实战',
- '疯狂iOS讲义','疯狂Java讲义'}:
- {'JavaScript: The Definitive Guide'}"
- doubleName="book"/>
- </s:form>
效果图:
2.5.9 optiontransferselect标签
optiontransferselect会生成两个列表选择框,并生成系列的按钮用于控制各选项在两个下拉列表之间的移动、升降等。当提交该表单时,两个列表选择框对应的请求参数都会被提交。因为该标签会生成两个列表框,因此需要分别制定两个列表框中的集合、lable等属性,下面是该标签常用的属性:- addAllToLeftLable:设置全部移动到左边按钮上的文本
- addAllToRightLable:设置全部移动到右边按钮上的文本
- addToLeftLable:设置向左移动按钮上的文本
- addToRightLable:设置向右移动按钮上的文本
- allowAddAllToLeft:设置是否出现全部移动到左边的按钮
- allowAddAllToRight:设置是否出现全部移动到右边的按钮
- allowAddToLeft:设置是否出现移动到左边的按钮
- allowAddToRight:设置是否出现移动到右边的按钮
- leftTitle:设置左边列表框的标题
- rightTitle:设置右边列表框的标题
- allowSelectAll:设置是否出现全部选择按钮
- selectAllLable:设置全部选择按钮上的文本
- doubleList:必填属性,设置用于创建第二个下拉框的集合
- doubleListKey:设置第二个下拉选择框的选项value的属性
- doubleListValue:设置创建第二个下拉选择框的选项label的属性
- doubleName:必填属性,设置第二个下拉选择框的name属性
- doubleValue:设置第二个下拉选择框的value属性
- doubleMultiple:设置第二个下拉选择框是否允许多选
- list:设置用于创建第一个下拉选择框的选项value的属性
- listKey:设置创建第一个下拉选择框的选项value的属性
- listValue:设置创建第一个下拉选择框的选项label的属性
- name:设置第一个下拉选择框的name属性
- value:设置第一个选择框的value属性
- multiple:设置第一个下拉选择框是否允许多选
示例如下:
- <h3>使用s:optiontransferselect来生成可移动列表项的下拉列表框</h3>
- <s:form>
- <!-- 使用简单集合对象来生成可移动的下拉列表框 -->
- <s:optiontransferselect
- label="请选择你喜欢的图书"
- name="cnbook"
- leftTitle="中文图书:"
- rightTitle="外文图书"
- list="{'疯狂Java讲义' ,'疯狂iOS讲义',
- '轻量级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>
效果图:
2.5.10 token标签
这是一个防止重复提交表单的标签,token标签能组织重复提交表单的问题(避免刷新页面导致的重复提交)。如果需要该标签起作用,则应该在Struts2的配置文件中启用TokenInterceptor拦截器或TokenSessionStoreInterceptor拦截器。这个标签无需在页面上生成任何输出,也无需开发者手动控制,因此使用该标签无须指定任何属性。
原理:token标签的实现原理是在表单中增加一个隐藏域,每次加载该页面时,该隐藏域的值都不相同。而TokenInterceptor拦截器则拦截所有用户请求,如果两次请求时该token对隐藏域的值相同(前一次提交时token隐藏域的值保存在session里),则阻止表单提交。
注意:在默认情况下,token标签生成的隐藏域的name为struts.token。因此,不要在表单中另外定义一个名为struts.token的表单域。
示例如下:
- <h3>使用s:token防止重复提交</h3>
- <s:form action="pro">
- <!-- 普通表单域 -->
- <s:textfield name="book" label="书名"/>
- <!-- 用于防刷新的token -->
- <s:token/>
- <s:submit value="提交"/>
- </s:form>
- <!-- 定义名为pro的Action,其实现类为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">/WEB-INF/content/refresh.jsp</result>
- <!-- 如果处理结果返回success,对应/show.jsp视图资源 -->
- <result>/WEB-INF/content/show.jsp</result>
- </action>
- 页面中添加token标签
- 配置Action时启动token拦截器,并为invalid.token逻辑视图指定物理资源
注意:如果表单页面没有使用<s:token/>标签,则千万不要使用token拦截器,否则它将导致无法提交表单。
效果图:
2.6 非表单标签
非表单标签主要用于在页面中生成一些非表单的可视化元素,例如Tab页面、输出HTML页面的树形结构等。当然,非表单标签也包含在页面中显示Action里封装的信息。非表单标签主要有如下几个:
- actionerror:如果Action实例的getActionErrors()方法返回不为null,则该标签负责输出该方法反悔的系列错误
- actionmessage:如果Action实例的getActionMessages()方法返回不为null,该标签负责输出该方法返回的系列信息
- component:使用此标签可以生成一个自定义组件
- fielderror:如果Action实例存在表单域的类型转换错误、校验错误,该标签则负责输出这些错误提示
《轻量级JavaEE企业应用实战 第四版》
最后修改时间:2017年3月29日16:13:35
********************************************************************************结束语********************************************************************************************
我在写这篇博客的时候也是一名初学者,有任何疑问或问题请留言,或发邮件也可以,邮箱为:[email protected],我会尽早的进行更正及更改。
在我写过的博客中有两篇博客是对资源的整理,可能对大家都有帮助,大家有兴趣的话可以看看!!
下载资料整理——目录:http://blog.csdn.net/fanxiaobin577328725/article/details/51894331
这篇博客里面是我关于我见到的感觉不错的好资源的整理,里面包含了书籍及源代码以及个人搜索的一些资源,如果有兴趣的可以看看,我会一直对其进行更新和添加。
优秀的文章&优秀的学习网站之收集手册:http://blog.csdn.net/fanxiaobin577328725/article/details/52753638
这篇博客里面是我对于我读过的,并且感觉有意义的文章的收集整理,纯粹的个人爱好,大家感觉有兴趣的可以阅读一下,我也会时常的对其进行更新。