struts2学习之---标签库

struts2把所有标签都定义在一个s标签库里,定义在URI为”/struts-tags”的空间里。
struts2可以将所有标签分为如下三类:

  • UI(User Interface,用户界面)标签:主要用于生成HTML元素的标签。
  • 非UI标签:主要用于数据访问、逻辑控制等的标签。
  • Ajax标签:用于Ajax支持的标签。

    对于UI标签,则又可分为如下两类:

  • 表单标签:主要用于生成HTML页面的form元素,以及普通表单元素的标签。
  • 非表单标签:主要用于生成页面上的树、Tab页等标签。

    对于非UI标签,也可分为如下两类:

  • 流程控制标签:主要包含用于实现分支、循环等流程控制的标签。
  • 数据访问标签:主要包含用于输出ValueStack中的值、完成国际化等功能的标签。

    1.使用struts2标签

    标签库的开发包括两个步骤:开发标签处理类和定义标签库定义文件。struts2已经完成了这两个步骤,即struts2既提供了标签的处理类,也提供了struts2的标签库定义文件。
    struts2-core-2.3.16.3.jar/META-INF路径下找到struts2-tags.tld就是struts2的标签库定义文件。

    struts-tags.tld
    <short-name>s</short-name>
    <uri>/struts-tags</uri>
    
    jsp
    <%@taglib prefix="s" uri="/struts-tags"%>    
2.struts2的OGNL表达式

OGNL也不是真正的编程语言,只是一种数据访问语言。
在传统的OGNL表达式求值中,系统假设只有一个”根”对象。下面是标准OGNL表达式求值,如果系统的Stack Context中包含两个对象:foo对象,它在Context中的名字为foo;bar对象,它在Context中的名字为bar,并将foo对象设置成Context的根对象。

    //返回foo.getBlah()方法的返回值
    #foo.blah
    //返回bar.getBlah()方法的返回值
    #bar.blah
    //因为foo是根对象,所以默认是取得foo对象的blah属性,即返回
    //foo.getBlah()方法的返回值
    blah   
    #bar.foo.blah

返回的是bar.getFoo().getBlah()方法的返回值。如果需要访问的属性属于根对象,则可以直接访问该属性,如:blah;否则必须使用一个对象名作为前缀修饰该属性,如#bar.blah。struts2提供了一个特殊的OGNL PropertyAccessor(属性访问器),它可以自动搜寻Stack Context的所有实体(从上到下),直到找到与求值表达式匹配的属性。
struts2使用标准的Context来进行OGNL表达式语言求值,OGNL的顶级对象是Stack Context,Stack Context对象就是一个Map类型的实例,其根对象就是ValueStack,如需要访问ValueStack里的属性,直接通过如下方式:

    //取得ValueStack中的bar属性
    ${bar}  

struts2还提供了一些命名对象,但这些命名对象都不是Stack Context的”根”对象,他们只是存在于Stack Context中,所以访问这些对象命名时需要使用#前缀来指明。

  • parameter对象:用于访问HTTP请求参数,例如#parameters[‘foo’]或#parameters.foo,用于访问调用HttpServletRequest的getParameter(“方法”)的返回值。
  • request对象:用于访问HttpServetRequest的属性,例如#request[‘foo’]或#request.foo,用于返回调用HttpServletRequest的getAttribute(“foo”)的返回值
  • session对象:用于访问HttpSession的属性。
  • application对象:用于访问ServletContext的属性。
  • attr对象:该对象将依次搜索如下对象:PageContext、HttpServletRequest、HttpSession、ServletContext的属性。

当系统创建了Action实例后,该Action实例已经被保存到ValueStack中,故无须书写#即可访问Action属性。
OGNL的Stack Context是整个OGNL计算、求值的Context,而ValueStack只是StackContext内的”根”对象而已。

  • 访问Stack Context里的命名对象需要在对象名之前添加#前缀。
  • 当访问OGNL的Stack Context里”根”对象的属性时,可以省略对象名。

可以在任意页面增加java<s:debug/>标签,该标签将生成一个链接,泳衣辅助开发者进行调试。

3.OGNL中的集合操作

OGNL可以直接创建对象:
1. 直接创建List类型集合的语法为:
{e1,e2,e3…}
2. 直接生成Map类型集合的语法为:
#{key1:value1,key2:value2,...}
对于集合,OGNL提供了两个运算符:in和not in,其中in判断某个元素是否在指定集合中;not in则用于判断某个元素是否不再指定集合中。

    <s:if test="'foo' in {'foo','bar'}">

除此之外,OGNL还允许通过某个规则取得集合的子集:

  • ?:取出所有符合选择逻辑的元素。
  • ^:取出符合选择逻辑的第一个元素。
  • $:取出符合选择逻辑的最后一个元素。
    //取出person的所有性别为male的relatives(亲戚)集合
    person.relatives.{? #this.gender == 'male'}
4.访问静态成员

为了让OGNL表达式可以访问静态方法,应该在Struts2应用中将struts.ognl.allowStaticMethodAccess设置为true。

  struts.xml
  <content name="struts.ognl.allowStaticMethodAccess" value="true"/>

一旦设置了上面所示常量,OGNL表达式可以通过如下语法来访问静态成员:

  • @classNmae@staticField
  • @className@staticMethod(val…)
    <s:property value="@java.lang.Math@PI">
5.Lambda表达式

OGNL支持基本的Lambda表达式语法,通过这种表达式语法,可以允许程序员在OGNL表达式中使用一些简单的函数:

斐波那契数列:
if n==0 return 0;
elseif n==1 return 1;
else return fib(n - 2) + fib(n - 1);

//使用OGNL表达式求该数列中第11个元素的值:
<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this - 2)+ #fib(#this-1)],#fib(11)"/> 
6.控制标签

主要用于完成流程控制,以及操作struts2的ValueStack。
1. if/elseif/else 标签
if 标签和else 标签可接受一个test属性,该属性确定执行判断的boolean表达式。
2. iterator标签
可指定三个属性为:

  • value:用于指定被迭代的集合,被迭代的集合通常都使用OGNL表达式指定。如果没有指定value属性,则使用ValueStack栈顶的集合。
  • id:该属性指定了集合里元素的ID。
  • status:该属性指定迭代是的IteratorStatus实例。
    IteratorStatus实例,该实例包含了如下几个方法:
  • int getCount():返回当前迭代了几个元素。
  • int getIndex():返回当前迭代元素的索引。
  • boolean isEven():返回当前被迭代元素的索引是否是偶数。
  • boolean isFirst():返回当前被迭代元素是否是第一个元素。
  • boolean isLast():返回当前被迭代元素是否是最后一个元素。
  • boolean idOdd():返回当前被迭代元素的索引是否是奇数。
    <s:iterator value="{'你好','你好吗','你真的好吗'}" 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>  

3.append标签
append标签用于将多个集合对象拼接起来,组成一个新的集合。

<s:append var="newList">
    <s:param value="{'1','2','3'}"/>
    <s:param value="{'4','5','6'}"/>
</s:append>

4.generator标签
使用generator标签可以将制定字符串按制定分隔符分隔成多个字符串,临时生成的多个子串可以使用iterator标签迭代输出。可以理解为:generator将一个字符串转化成一个Iterator集合,在该标签体内,整个临时生成的集合将位于ValueStack的顶端,但一旦该标签结束,该集合将被移出ValueStack。generator的标签有点类似于String对象的split()方法,但这个标签比split()方法的功能更强大。

  • count:该属性指定生成集合中元素的总数。
  • separator:必填属性,该属性指定用于解析字符串的分隔符。
  • val:必填属性,该属性指定被解析的字符串。
  • converter:该属性指定一个转换器,该转换器负责将集合中的每个字符串转换成对象,通过该转换器可以将一个字符串解析成对象集合。该属性值必须是一个org.apache.Struts2.util.IteratorGenerator.Converter对象。
  • var:如果指定了该属性,则将生成的Iterator对象放入Stack Context中。

5.merge标签
采用append和merge方式合并集合时,新集合中集合元素完全相同,只是新集合中集合元素的顺序有所不同。

6.subset标签
subset标签用于取得集合的子集,该标签的底层通过org.apache.struts2.util.SubsetIteratorFilter类提供实现。

  • count:该属性指定子集中元素的个数。
  • source:该属性指定源集合,如果不指定,则默认取得ValueStack栈顶的集合。
  • start:该属性指定子集从源集合的第几个元素开始截取。默认从第一个元素(即start的默认值为0)开始截取。
  • decider:该属性指定由开发者自己决定是否选中该元素。该元素必须指定一个org.apache.struts2.util.SubsetIteratorFilter.Decider对象。
  • var:如果指定了该属性,则将生成的Iterator对象设置成page范围的属性。
    subset标签生成的子集合放在ValueStack的栈顶,所以可以在该标签内直接迭代该标签生成的子集合。

7.sort标签
sort标签用于对指定的集合元素进行排序,进行排序时,必须提供自己的排序规则,即实现自己的Comparator,自己的Comparator需要实现java.util.Comparator接口。

  • comparator:必填的属性,该属性指定进行排序的Comparator实例。
  • source:该属性指定被排序的集合,如果不指定该属性,则对ValueStack栈顶的集合进行排序。
  • var:只是将排序后的新集合放入pageScope中,并未放入OGNL的Stack Context中。
    在sort标签体内时,sort标签生成的子集合放在ValueStack的栈顶,所以可以在该标签内直接迭代该标签生成的子集合。
    public class MyComparator implements Comparator{
        public int compare(Object element1,Object element2){
            return element1.toString().length() - element2.toString().length();
        }
    }

如果该方法返回一个大于0的整数,则第一个元素大于第二个元素;如果该方法返回0,则两个元素相等;如果该方法返回小于0的整数,则第一个元素小于第二个元素。

    <s:bean var="mycomparator" name=""/>
    <s:sort source="{'1','2','3'}" comparator="#mycomparator" var="sortedList"/>
7.数据标签

数据标签主要用于提供各种数据访问相关的功能,包含显示一个Action里的属性,以及生成国际化输出等功能。

  1. action标签
    使用action标签可以允许在JSP页面中直接调用Action

    • var:该Action将被放入Stack Context中。
    • name:必填属性,通过该属性指定该标签调用哪个Action。
    • namespace:该属性指定该标签调用的Action所在的namespa。
    • executeResult:该属性指定是否要将Action的处理结果页面包含到本页面。该属性值默认值是false,即不包含。
    • ignoreContextParams:指定该页面中的请求参数是否需要传入调用的Action。默认值是false,即将本页面的请求参数传入被调用的Ation。
  2. bean标签
    bean标签用于创建一个JavaBean实例。

    • name:该属性是一个必填属性,该属性指定要实例化的JavaBean的实现类。
    • var:如果指定了该属性,则该JavaBean实例会被放入Stack Context中,并放入requestScope中。
    <s:bean name="">
        <!--使用param标签为Person类的实例传入参数-->
        <s:param name="name" value="huang"/>
        <s:param name="age" value="20"/>
    </s:bean>

3.date标签
date标签用于格式化输出有个日期,除了可以直接格式化输出一个日期外,date标签还可以计算指定日期和当前时刻之间的时间差。

  • format:指定了该属性,将根据该属性指定的格式来格式化日期。
  • nice:该属性只有true或false,它用于指定是否输出指定日期和当前时刻之间的时间差。默认值是false。
  • name:必填属性,指定要格式化的日期值。
  • var:如果指定了该属性,格式化后的字符串将被放入Stack Context中,并放入requestScope中,但不会在页面上输出。
    通常,nice属性和format属性不同时指定。
    如果同时指定,则format属性失效;如果都没有指定,则系统会到国际化资源文件中寻找key为struts.date.format的消息,将该消息当成格式化文本来格式化日期,如果没有找到,怎默认采用DateFormat.MRDIUM格式输出。

4.debug标签
debug标签主要用于辅助调试,它在页面上生成一个超链接,通过该链接可以查看到ValueStack 和 Stack Context中所有的值信息。

5.include标签
include标签用于将一个JSP页面,或者一个Servlet包含到本页面

  • value:必填属性,该属性指定需要被包含的JSP页面,或者Servlet。
    除此之外,还可以为<s:include.../>标签指定多个<param.../>子标签,用于将多个参数值传入被包含的JSP页面或者Servlet。

6.param标签
param标签主要用于为其他标签提供参数,例如,为include和bean标签提供参数。

  • name:指定需要设置参数的参数名。
  • value:指定需要设置参数的参数值。

7.push标签
push标签用于将某个值放到ValueStack的栈顶,从而可以更简单地访问该值。

  • value:必填属性,该属性指定需要放到ValueStack栈顶的值。

8.set标签
set标签用于将某个值放入指定范围内。
使用set标签可以理解为定义一个新变量,且将一个已有的值复制给新变量,并且可以将新变量放到指定的范围内。

  • scope:指定新变量被放置的范围,该属性可以接受application、session、request、page、action。默认值是action。
  • value:指定将赋给变量的值,如果没有指定该属性,则将ValueStack栈顶的值赋给新变量。
  • var:如果指定了该属性,则会将该值放入ValueStack中。
    如果指定action范围,则该值将被放入request范围中,并被放入OGNL的Stack Context中。
    9.url标签
    url标签用于生成一个URL地址,可以通过为url标签指定param参数,从而向指定URL发送请求参数。

  • action:指定生成URL地址为哪个Action,如果Action不提供,就使用value作为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:用于设置scheme属性。
  • value:指定生成URL的地址值,如果value不提供就用action属性指定的Action作为URL地址。
  • var:如果指定了该属性,将会把该链接值放入Struts2的ValueStack中。
  • window:指定结果页面的portlet的窗口状态。

10.property标签
property标签的作用是输出指定值。property标签输出value属性指定的值,如果没有指定value属性,则默认输出ValueStack栈顶的值。

  • default:如果需要输出的属性值为null,则显示default属性指定的值。
  • escape:指定是否escapeHTML代码。默认是true。
  • value:指定需要输出的属性值,如果没有指定该属性,则默认输出ValueStack栈顶的值。
8.主题和模板

因为struts2所有的UI标签都是基于主题和模板的,主题和模板是struts2所有UI标签的核心。模板是一个UI标签的外在形式。如果为所有的UI标签都提供了对应的模板,那么这系列的模板就形成一个主题。
对于一个JSP页面里包含的UI标签,既可以直接设置该UI标签需要使用的模板,也可以设置该UI标签使用的主题。实际上,并不推荐直接设置模板属性,因为模板属性是以主题的形式组织在一起的,界面开发者应该选择特定的主题。
主题是模板的组织形式,模板被包装在主题里面,对于开发者应该是透明的,当需要使用特定模板来表现某个UI标签时,应该让主题来负责模板的加载。
设置主题的方法有如下几种:

  • 通过设定特定的UI标签上的theme属性来指定主题。
  • 通过设定特定UI标签外围的<s:form.../>标签的theme属性来指定主题。
  • 通过取得page会话范围内以theme为名称的属性来确定主题。
  • 通过取得request会话范围内以theme为名称的属性来确定主题。
  • 通过取得session会话范围内以theme为名称的属性来确定主题。
  • 通过取得application会话范围内以theme为名称的属性来确定主题。
  • 通过设置名为struts.ui.theme的常量(默认值是xhtml)来确定主题。
    它们有着不同的优先级,排在前面的方式会覆盖排在后面的方式。

如果需要改变整个表单(包括表单元素的主题),则可以直接设置该表单标签的theme属性,如果需要让某次用户会话使用特定的主题,则可以通过在session中设置一个theme的变量。如果想改变整个应用的主题,则应该通过修改struts.ui.theme常量值来实现。struts2加载模板是通过主题和模板目录来实现的。
模板目录是存放所有模板文件的地方,所有的模板文件以主题的方式来租住,模板目录是通过struts.ui.templateDir常量来指定的,该常量的默认值是template,即意味着从WEB应用的template目录、CLASSPATH的template目录来依次加载特定模板文件。
加载模板文件的顺序:
(1)搜索Web应用里/template/xhtml/select.ftl
(2)搜索CLASSPATH路径下的/template/xhtml/select.ftl
struts2默认的模板文件时*.ftl,该文件时FreeMarker模板文件。
struts2默认提供了三个主题:simple、xhtml和css_xhtml。
simple主题是最简单的主题,使用它时,每个UI标签只生成一个简单的HTML元素,不会生成其他额外的内容,不会有额外的布局行为。其他两个主题都是对simple主题的包装和扩展。
xhtml主题是Struts2默认的主题,其特性如下:

  • 针对HTML标签(如textfield和select标签)使用标准的两列表格布局。
  • 每个HTML标签增加了配套的label,label既可以出现在HTML元素的左边,也可以出现在上边,这取决于labelposition属性的设置。
  • 自动输出校验错误提示。
  • 输出javascript的客户端校验。
9.自定义主题

struts2允许通过对现有主题进行包装来创建自定义主题,所谓包装就是在现有主题基础上,增加一些自定义代码部分,从而完成修改。
自定义一个ftl文件,开发者必须为每个UI组件都提供自定义的模板文件。除此之外,还必须在主题目录下增加一个theme.properties文件,该文件指定自定义模板是以哪个模板为基础进行扩展的。

    parent=xhtml
10.表单标签

表单标签分为:form标签本身和单个表单元素的标签。
所有的表单标签处理类都继承了UIBean类,UIBean包含了一些通用属性:

  • 模板相关属性。
  • JavaScript相关属性。
  • 通用属性。
    所有表单元素标签都存在一个特殊的属性:form,这个属性引用表单元素所在的表单,通过该form属性,可以实现表单元素的表单之间的交互。例如可通过${parameters.form.id}来取得表单元素所在表单的ID。

    1. 表单标签的name和value属性
      name和value属性之间存在一个特殊的关系:因为每个表单元素会被映射成Action属性,所以如果某个表单对应的Action已经被实例化(该表单提交过)、且属性有值是,则该Action对应表单里的表单元素会显示出该属性的值,这个值将作为表单标签的value值。
      name属性设置表单元素的名字,表单元素的名字实际上封装着一个请求参数,而请求参数是被封装到Action属性的。因此,可以将该name属性指定为你希望绑定值的表达式。
    2. checkboxlist标签
      checkboxlist标签可以一次创建多个复选框,用于同时生成多个<input type="checkbox".../>的HTML标签。它根据list属性指定的集合来生成多个复选框,因此,使用该标签指定一个list属性。

      • listKey:该属性指定集合元素中的某个属性作为复选框的value。
      • listValue:该属性指定集合元素中的某个属性作为复选框的标签。
    3. radio标签
      radio标签的用法与checkboxlist的用法几乎完全相同,不同的是radio生成的是多个单选钮。
    4. select标签
      select标签用于生成一个下拉列表框,其用法与checkboxlist标签的用法非常相似,多了一个属性:

      • multiple:设置该列表框是否允许多选。
    5. optgroup标签
      optgroup标签用于生成一个下拉列表框的选项组,因此,该标签必须放在<s:select.../>标签中使用。
      optgroup标签与select标签类型,其也可以指定label属性,但这个label属性不是下拉列表框的label,而是该选项组的组名。
    6. head标签
      该标签主要用于生成HTML页面的<head.../>部分。
    7. updownselect标签
      updownselect标签的用法非常类似于select标签的用法,区别是该标签生成的列表框可以上下移动选项。多了如下几个属性:

      • allowMoveup:是否显示”上移”按钮,默认是true。
      • allowMoveDown:是否显示”下移”按钮,默认是true。
      • allowSelectAll:是否显示”全选”按钮,默认是true。
      • moveUpLabel:设置”上移”按钮上的文本,默认是^符号。
      • moveDownLabel:设置”下移”按钮上的文本,默认是v符号。
      • selectAllLabel:设置”全选”按钮上的文本,默认是*符号。
      • 指定empeyOption=”true”属性,因此会为该列表框增加一个空选项。
    8. doubleselect标签
      doubleselect标签会生成一个级联列表框(会生成两个下拉列表框),当选择第一个下拉列表框时,第二个下拉列表框的内容会随之改变。
<s:form>    
    <s:doubleselect label="请选择您喜欢的图书" name="author" list="{'huang','qi'}" doubleList="top == 'huang' ? {'nihao','nizhenhao'} : {'你好','你真好'}" doubleName="book"/>
</s:form>

在默认情况下,第一个下拉列表框只支持两项,如果第一个下拉列表框包含三个或更多的值,可以采用迂回方式来实现,首先定义一个Map对象,该Map对象的value都是集合,这样就能以Map对象的对个key创建第一个下拉列表框的列表项,而每个key对应的集合则用于创建第二个下拉列表框的列表项。

<s:set name="bs" value="#{'huang':{'nihao','nizhenhao'},'Don':{'你好'},'Jon':{'你真好'}}"/>
<s:form action="">
    <s:doubleselect label="请选择您喜欢的图书" size="3" name="author" list="#bs.keySet()" doubleList="#bs[top]" doubleSize="3" doubleName="book"/>
</s:form>

9.optiontransferselect标签
optintransferselect会生成两个列表选择框,并生成系列的按钮用于控制各选项在两个下拉列表之间的移动、升降等,当提交该表单时,两个列表选择框对应的请求参数都会被提交。
10.token标签
这是一个用于防止重复提交表单的表单,token标签能阻止重复提交表单的问题(避免刷新页面导致的重复提交)。如果需要该标签起作用,则应该在struts2的配置文件中启用TokenInterceptor或TokenSessionStoreInterceptor拦截器。
token标签的实现原理是在表单中增加一个隐藏域,每次加载该页面时,该隐藏域的值都不相同。而TokenInterceptor拦截器则拦截所有用户请求,如果两次请求时该token对应隐藏域的值相同(前一次提交时token隐藏域的值保存在session里),则阻止表单提交。
注意如下两步:

  • 页面中加token标签
  • 配置Action时启动token拦截器,并为invalid.token逻辑视图指定物理资源
11.非表单标签
  1. actionerror和actionmessage标签
    两个标签用法完全相同,都是负责输出Acion实例里封装的信息;区别是actionerror标签负责输出Action实例的getActionErrors()方法的返回值,而actionmessage标签负责输出Action实例的getActionMessages()方法的返回值。
  2. component标签
    component标签可用于创建自定义视图组件。

    • theme:自定义组件所使用的主题,默认使用xhtml主题。
    • templateDir:指定自定义组件的主题目录,默认使用template目录。
    • template:指定自定义组件所使用的模板。
      还可以在component标签内使用param子标签,子标签表示向该标签模板中传入额外的参数,采用:$parameters.paramName或者$parameters['paramName']形式.。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值