Struts2 标签库

java 同时被 3 个专栏收录
101 篇文章 0 订阅
25 篇文章 0 订阅
4 篇文章 0 订阅

Struts 2标签简介

与Struts1标签库相比,Struts 2 的标签库有一个巨大的改进之处: Struts2 标签库的标签不依赖于任何表现层技术,也就是说,Struts2 提供的大部分标签,可以在各种表现层技术中使用,包括最常用的JSP 页面,也可以在Velocity 和FreeMarker 等模板技术中使用。

虽然Struts 2 大部分标签可以在所有表现层技术中使用,但也有极少数标签在某些表现层技术中使用时会受到限制,这一点请开发者务必要注意。

Struts 标签分类

虽然Struts2 把所有的标签都定义在URI 为“/struts-tags”的空间下,但我们依然可以对Struts2 标签进行简单的分类。

Struts2 可以将所有标签分成如下三类:

  • UI (User Interface,用户界面) 标签: 主要用于生成HTML 元素的标签。
  • 非UI 标签: 主要用于数据访问、逻辑控制等的标签。
  • Ajax 标签: 用于Ajax (Asynchronous JavaScript And XML) 支持的标签。
  • 表单标签: 主要用于生成HTML 页面的form 元素,以及普通表单元素的标签。
  • 非表单标签: 主要用于生成页面上的树、Tab 页等标签。
  • 流程控制标签: 主要包含用于实现分支、循环等流程控制的标签。
  • 数据访问标签: 主要包含用于输出ValueStack 中的值、完成国际化等功能的标签。

这里写图片描述

使用Struts标签库

在使用的时候,还是需要添加这一指令。

<%@taglib prefix="s"  uri="/struts-tags"%>

在上面标签中,因为该标签以“s”作为前缀,故该标签需要使用URI 为/struts-tags 的标签库处理,通过前缀关联,系统知道从Struts 2 标签库中寻找名为abc 的标签来处理相应标签。

OGNL

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,他是一个开源项目。Struts框架使用OGNL作为默认的表达式语言。

在Struts2 应用中,视图页面可通过标签直接访问Action 属性值( 实际上这只是一种假想,类似于Web 应用application.session.request和page 四个范围的“银行”一样,Struts2 自行维护一个特定范围的“银行”, Action 将数据放入其中,而JSP 页面可从其中取出数据,表面上似乎JSP 可直接访问Action 数据),当Action属性不是简单值(基本类型值或String类型值) 时,而是某个对象,甚至是数组、集合时,就需要使用表达式语言来访问这些对象、数组、集合的内部数据了, Struts 2 利用OGNL 表达式语言来实现这个功能。

这里写图片描述

在传统的OGNL 表达式求值中,系统会假设只有一个“根”对象。下面是标准OGNL 表达值,如果系统的StackContext 中包含两个对象: foo 对象,它在Context 中的名字为foo; bar对象,在Context 中的名字为bar,并将foo 对象设置成Context 的根对象。

//返回foo.getBlah () 方法的返回值,属性一般都有set、get方法。
#foo.blah
//返回bar.getBlah() 方法的返回值
#bar.blah
//因为foo 是根对象,所以默认是取得foo对象的blah属性
blan

如果需要访问的属性属于根对象,则可以直接访问该属性,如blah; 否则必须使用一个对象名作为前缀修饰该属性,如#bar.blah。

Struts 2 使用标准的Context 来进行OGNL 表达式语言求值,OGNL 的顶级对象是一个Context,这个Context 对象就是一个Map 类型实例,根对象有是ValueStack对象。

存放在ValueStack里面可以通过${属性名}(el表达式),直接获取。

值栈的简单定义:

  • 简单的说,值栈是对应每一个请求对象的轻量级的数据存储中心,在这里统一管理着数据,供Action、Result、Interceptor等Struts2的其他部分使用,这样数据被集中管理起来而不凌乱。
  • 当有请求的时候,Struts2会为每个请求创建一个新的值栈,也就是说,值栈和请求是一一对应的,不同的请求,值栈也不一样, 而值栈封装了一次请求所有需要操作的相关的数据。
  • 正是因为值栈和请求的对应关系,因此值栈能保证线程安全的为每个请求提供公共的数据存取服务。
  • 就是ROOT根对象,ognl访问值栈不用加任何的访问前缀,只需action中声明相应的属性,并且生成属性对应的set和get方法,页面中通过struts2标签就可以存放/取出值栈中的值,EL表达式${username}如果没有加访问范围,访问的也是值栈,这只是最简单的值栈应用
  • 值栈的特点:如果访问的值栈里有多个对象,且相同的属性在多个对象中同时出现,则值栈会按照从栈顶到栈底的顺序,寻找第一个匹配的对象。

参考学习:这里写链接内容

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

注意:OGNL 的Stack Context 是整个OGNL 计算、求值的Context,而ValueStack 只是StackContex 内的“根”对象而已。OGNL 的Stack Context里除了包括ValueStack 这个根之外,还包括parameters.request.session.application.attr 等命名对象,但这些命名对象都不是根。Stack Context “根”对象和普通命名对象的区别在于:

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

这里写图片描述

OGNL集合运算

创建List类型集合的语法:

{e1,e2,e3....}

创建Map类型集合的语法:

#{key1:value1,key2:value2....}

多个元素之间用英文隔开。

对于集合,OGNL 提供了两个运算符: in 和notin,其中in 判断某个兀素是含在指定集合中; not in 则用于判断某个元素是否不在指定集合中。

除此之外,OGNL 还允许通过某个规则取得集合的子集。取得子集时有如下三个操作符:

  1. ? 取出所有符合选择逻辑的元素。
  2. ^取出符合选择逻辑的第一个元素。
  3. $: 取出符合选择逻辑的最后一个元素。

person.relatives.{? #this.gender== ‘male’} ,直接在集合后紧跟.{ }运算符表明用于取出该集合的子集,在{ }内使用?表明取出所有符合选择逻辑的元素,而#this 代表集合里元素。因此,上面代码的含义是: 取出person 的所有性别为male 的relatives (亲戚) 集合。

OGNL表达式对静态属性的访问

为了让OGNL对静态属性的设置,需要在Struts.xml中进行设置。

OGNL 表达式可以通过如下语法来访问静态成员:

<constant name="struts.oqn1.allowStatiaMethodAccess" value="true"></constant>
@classNameQstaticField
@className@staticMethod(val...)
    <s:property value="@java.lang.Math@PI"></s:property>

控制标签

  • if: 用于控制选择输出的标签。
  • elself/elseif: 与if 标签结合使用,用于控制选择输出的标签。else: 与if 标签结合使用,用于控制选择输出的标签。
  • append: 用于将多个集合拼接成一个新的集合。
  • generator:它是一个字符串解析器,用于将一个字符串解析成一个集合。iterator: 这是一个迭代器,用于将集合迭代输出。
  • merge: 用于将多个集合拼接成一个新的集合。但与append 的拼接方式有所不同。sort: 这个标签用于对集合进行排序。
  • subset: 这个标签用于截取集合的部分元素,形成新的子集合。
if/else if/else

这三个标签可以组合使用,只有<…>标签可以单独使用,后面的

 <s:set value="90" var="age"/>
 <s:if test="#age>60">老年人</s:if>//test是对条件
 <s:elseif test="#age>35">中年人</s:elseif>
 <s:else>年轻人</s:else>
 <s:debug></s:debug>

这里写图片描述

我们通过可以看到它把该属性添加到Stack Context中了。

iterator

iterator 标签主要用于对集合进行迭代,这里的集合包含List、Set 和数组,也可对Map 集合进行迭代输出。使用

 <table border="2px">
      <s:iterator value="{'laoqiang','laoqiangtest','laoqiangtest1'}" var="name" status="st">//value构造的集合是通过OGNL来创建,var是给迭代器起的名字,方便你去引用。
      <tr <s:if test="#st.odd">style="background-color:#bbbbbb"</s:if>>//通过设置迭代的的索引奇数,来设置行的背景颜色。
      <td>
      <s:property value="#st.count"/>
      <s:property value="name"></s:property>
      </td>
      </tr>
      </s:iterator>
    </table>

  <s:append var="newlist1">
      <s:param value="#{'name':'laoqiang','age':'12','sex':'man'}"></s:param>
      <s:param value="#{'test1','test3','test2'}"></s:param>
      </s:append>
  <table>
 <s:iterator value="#newlist1" status="sttt1" var ="new2">
      <tr>
      <td>
      <s:property value="key"></s:property></td>
      <td>
      <s:property value="value"/>
      </td>
      </tr>
      </s:iterator>
</table>

在该例子中,我们展示了在对map集合的合并,与遍历显示,同时我们还需要知道,在map中,如果没有value,只有key,那么显示的时候,就按照key显示。

这里写图片描述

generator

使用generator标签可以将指定字符串按指定分隔符分隔成多个子串,临时生成的多个子串可以使用iterator 标签来迭代输出。可以这样理解: generator将一个字符串转化成一个Iterator 集合。在该标签的标签体内,整个临时生成的集合将位于ValueStack 的顶端,但一旦该标签结束,该集合将被移出ValueStack。

  • count : 该属性是一个可选的属性,该属性指定生成集合中元素的总数。
  • separator: 这是一个必填的属性,该属性指定用于解析字符串的分隔符。
  • val: 这是一个必填的属性,该属性指定被解析的字符串。
  • converter: 这是一个可选的属性,该属性指定一个转换器,该转换器负责将集合中的每个字符串转换成对象,通过该转换器可以将一个字符串解析成对象集合。该属性值必须是一个org.apache.Struts.util.lteratorGenerator.over 对象。
  • var: 这是 一个可选的属性,如果指定了该属性,则将生成的Iterator 对象放入StackContext中。该属性也可替换成id,但推荐使用var 属性。
 <s:generator separator="," val="'laoqiang,laoqiange,laoqiangt'" var="books">
    <s:debug></s:debug>
    <table border="1px">
    <s:iterator>
    <tr>
    <td>
    <s:property></s:property>
    </td>
    </tr>
    </s:iterator>
    </table>
    </s:generator>
    ${requestScope.books}

如果指定了var 属性,就可将生成的集合放入Struts 2 的Stack Context 中(实际上还会设置成request 范围的属性)。

Struts2 的很多标签都与该标签类似,它们都可以指定var (以前是id )属性,一旦指定了var 属性,则会将新生成、新设置的值放入Stack Context 中(必须通过#name 形式访问); 如果不指定var属性, 则新生成、新设置的值不会放入Stack Context 中, 因此只能在该标签内部访问新生成、新设置的值一一此时新生成、新设置的值位于ValueStack中, 因此可以直接访问。

merge

该标签和append一样的功能,都是将多个集合合并成一个集合,但是区别就在于添加的顺序不同。

这里写图片描述

这里写图片描述

 <s:merge var="list" >
     <s:param value="{'laoqiang','laoqiang1','laoqiang2'}"></s:param>
      <s:param value="{'laoqiang3','laoqiang4','laoqiang5'}"></s:param>
     </s:merge>
     </table>
     <s:iterator value="#list" var="list1">
     <tr>
     <td>
     <s:property value="#list1"></s:property>
     </td>
     </tr>
     </s:iterator>
     </table>
subset

subset标签用于取得集合的子集。

  • count: 这是一个可选属性,该属性指定子集中元素的个数。如果不指定该属性,则默认取得源集合的全部元素。
  • source:这是一个可选属性,该属性指定源集合。如果不指定该属性,则默认取得ValueStack栈顶的集合。
  • start: 这是一个可选属性,该属性指定子集从源集合的第几个元素开始截取。默认从第一个元素(即start 的默认值为0) 开始截取。
  • decider:这是一个可选属性,该属性指定由开发者自己决定是否选中该元素。该属性必须指定一个org.apache.struts2.utilSubsetteratorFiler.Decidr对象。
  • var: 这是- 一个可选属性,如果指定了该属性,则将生成的Iterator 对象设置成page 范围的属性。
    该属性也可替换成id,但推荐使用var 属性。

在subset 标签内时,subset 标签生成的子集合放在ValueStack 的栈顶,所以我们可以在该标签内直接迭代该标签生成的子集合。如果该标签结束后,该标签生成的子集合将被移出ValueStack栈。

 <s:subset source="{'laoqiang','laoqiang1','laoqiang2','laoqiang3','laoqiang4','laoqiang5'}" start="1" count="4">
       <table border="2px">
     <s:iterator>
     <tr>
     <td><s:property></s:property></td>
     </tr>
     </s:iterator>
      </table>
     </s:subset>

我们可以自己定义截取子集的规则:

public class MyDe implements Decider{

    @Override
    public boolean decide(Object arg0) throws Exception {
        // TODO Auto-generated method stub
        String s = (String)arg0;
        return s.endsWith("3");
    }

}
<s:bean var="myde" name="com.example.test.MyDe"></s:bean> //通过var把这个bean对象添加statck context中,自己可以用<s:debug/>看。

     <s:subset source="{'laoqiang','laoqiang1','laoqiang2','laoqiang3','laoqiang4','laoqiang5'}" start="1" count="4" decider="#myde">//在Stack Context中获取非根对象。
       <table border="2px">
     <s:iterator>
     <tr>
     <td><s:property></s:property></td>
     </tr>
     </s:iterator>
      </table>
     </s:subset>
    <s:debug></s:debug>
  • comparator : 这是- 一个必填的属性,该属性指定进行排序的Comparator 实例。
  • source : 这是一个可选的属性, 该属性指定被排序的集合。如果不指定该属性, 则对ValueStack 栈顶的集合进行排序。
  • var: 这是一个可选的属性, 如果指定了该属性, 则将生成的Iterator 对象设置成page 范围的属性,不放入StackContext 中。该属性也可替换成id,但推荐使用var 属性。该属性的作用与subset 标签中var 属性的作用相同。
public class MyCom implements Comparator {

    @Override
    public int compare(Object o1, Object o2) {
        // TODO Auto-generated method stub
        return o2.toString().length()-o1.toString().length();
    }
}
 <s:bean var="mycom" name="com.example.test.MyCom"></s:bean>
    <s:sort source="{'laoqiasdng','laoqiasdsdsng1','laoqiasdsdng2','laoqisdsdsdsang3','sdsdsd','laoqiandssg5'}" comparator="#mycom">
    <table>
    <s:iterator>
    <tr>
    <td><s:property/></td>
    </tr>
    </s:iterator>
    </table>
    </s:sort>

数据标签

  • action: 该标签用于在JSP 页面直接调用一个Action,通过指定executeResult 参数,还可将该Action的处理结果包含到本页面中来。
  • bean: 该标签用于创建一个JavaBean 实例。如果指定了var 属性,则可以将创建的JavaBean实例放入StackContext 中。
  • date: 用于格式化输出一个日期。
  • debug: 用于在页面上生成一个调试链接,当单击该链接时,可以看到当前ValueStack 和Stack Context 中的内容。
  • i18n: 用于指定国际化资源文件的baseName.
  • include: 用于在JSP 页面中包含其他的JSP 或Servlet 资源。
  • param: 用于设置一个参数,通常是用做bean标签、ur|标签的子标签。
  • push : 用于将某个值放入ValueStack 的栈顶。
  • text: 用于输出国际化消息。
  • url: 用于生成一个URL 地址。
  • property: 用于输出某个值,包括输出ValueStack、Stack Context 和Action Context 中的值。
Action

在Struts 2中提供了在Jsp中直接调用Action。

  • var: 这是一个可选属性,一旦定义了该属性, 该Action 将被放入ValueStack 中, 该属性可用id代替,但推荐使用var。
  • name : 这是一个必填属性,通过该属性指定该标签调用哪个Action。
  • namespace : 这是一个可选属性,该属性指定该标签调用的Action所在的namespace。这里的namespace要和你在Struts.xml中填写的一致,否则会出问题。
  • executeResult: 这是一一个可选属性,该属性指定是否要将Action的处理结果页面包含到本页面。该属性值默认值是false, 即不包含。
  • ignoreContextParams:这是一个可选参数,它指定该页面中的请求参数是否需要传入调用的Action。该参数的默认值是false,即将本页面的请求参数传入被调用的Action。
public class TagAction extends ActionSupport {
    private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String execute1() throws Exception{
        ActionContext.getContext().put("username",getUsername());//在这直接获取url中的username参数。
        return "DONE";

    }
    <s:action name="tag1" executeResult="true" namespace="/" />
    <s:action name="tag2" executeResult="true" namespace="/"  ignoreContextParams="false"/>ignoreContextParams设置为true,是不接受任何参数到Action。

采用Get方法携带参数:http://localhost:8889/StrutsTag/index.jsp?username=helloword,注意这里的username,要和Action类的属性一致。

Bean

bean 标签用于创建一个JavaBean 实例。创建JavaBean 实例时,可以在该标签体内使用

<s:bean name="com.example.test.bean.Person">//这里的javabean是存放在ValueStack
      <s:param name="name" value="'laoqiang'"></s:param>//**注意这里的字符你需要加单引号。**
      <s:param name="age" value="12"></s:param>
      <s:property value="'laoqiang'"/>
      <s:property value="12"/>
      </s:bean>
      <s:bean name="com.example.test.bean.Person" var="personbean">//通过var将bean存放在stackcontext中,可以在<s:bean>外面去获取它的值。同时也存放在requestScope
      <s:param name="name" value="'laoqiang'"></s:param>
      <s:param name="age" value="12"></s:param>
      </s:bean>
      <s:property value="#personbean.name"/>
      <s:property value="#personbean.age"/>
Date

该标签主要用于显示时间。

  • format: 这是一个可选属性, 如果指定了该属性, 将根据该属性指定的格式来格式化日期。
  • nice: 这是一个可选属性,该属性只能为true或者false,它用于指定是否输出指定日期和当前时刻之间的时差。该属性默认是false,即表示不输出时差。
  • name : 这是一个必填属性,该属性指定要格式化的日期值。
  • var: 这是一个可选属性,如果指定了该属性,格式化后的字符串将被放入Stack Context 中,并放入requestScope 中,但不会在页面上输出。该属性也可用id 来代替,但推荐使用var。
      <s:bean var="date" name="java.util.Date">//必须要导入这个javabean对象
      </s:bean>
      <s:date name="#date" format="yy/MM/dd"/></br>
      <s:date name="#date" nice="true"/></br>
      <s:date name="#date"/>//如果nice是默认false,并且没有指定格式,是按照默认的struts时间格式显示,这个修改可以到struts的常量配置修改
      <s:date name="#date" var="time"/></br>//如果你指定var,是不显示时间的,需要你通过s:property配置显示。

      <s:property value="#time"/></br>//下面的显示都是按照默认的
      ${requestScope.time}
debug

该标签主要用于调试ValueStack和Stack Context的值的变化。

include

将jsp或者Servlet导入到该文件中。

     <s:include value="index1.jsp">
     <s:param name="username" value="'laoqiang'"></s:param>//可以传参数给包含的Jsp页面。
     <s:debug/>
     </s:include>
${param.username}
param

该标签在Struts中主要可以携带参数,用法在之前都已经用过。这个标签携带的参数是get传递。

其中,需要注意的传入的是字符串,要在字符串的外面添加单引号。

push

该标签将某个值放到ValueStack的栈顶,从而更简单的访问该值。

只有在push 标签内时,被push 标签放入ValueStack 中的对象才存在;一旦离开了push 标签,则刚刚放入的对象将立即被移出ValueStack。

  • value 该属性是指定要放入ValueStack的值。
      <s:bean name="com.example.test.bean.Person" var="person">
      <s:param name="name" value="'laoqiang'"/>
      <s:param name="age" value="123"/>
      </s:bean>
      //主要将一个javabean放入到StackContext,在将它放入到ValueStack中
      <s:push value="#person">
      <s:property value="name"/>
      <s:property value="age"/>
      </s:push>
Set

set 标签用于将某个值放入指定范围内,例如application 范围、 session范围等。当某个值所在对象图深度非常深时,例如有如下的值: person.worker.wife.pareag 每次访问该值不仅性能低下,而且代码可读性也差。为了避免这个问题,可以将该值设置成一个新值,并放入特定的范围内。

set 标签可以理解为定义一个新变量,且将一个已有的值复制给新变量,并且可以将新变量放到指定的范围内,原来对于Stack Context中,el表达式是不可以直接访问的。set 标签用于生成一个新变量,并且把该变量放置到指定范围内,这样就允许直接使用JSP2 表达式语言来访问这些变量了,当然也可通过Struts2 标签来访问它们。

  1. scope: 这是- 一个可选属性,指定新变量被放置的范围,该属性可以接受application,session、request.
    page 或action 5个值。该属性默认值是action。
  2. value: 这是- 一个可选属性,指定将赋给变量的值。如果没有指定该属性,则将ValueStack栈顶的值赋给新变量。
  3. var: 这是一个可选属性,如果指定了该属性,则会将该值放入ValueStack 中。

当把指定值放入特定范围时,范围可以是application、session.request.page 和action 5 个值,前面4 个范围很容易理解; 如果指定action 范围, 则该值将被放入request 范围中,并被放入OGNL 的Stack Context 中。

  <s:bean name="com.example.test.bean.Person" var="person">
  <s:param name="name" value="'laoqiang'"></s:param>
  <s:param name="age" value="1234"></s:param>
  </s:bean>
     <s:set value="#person" var="newperson"/>//默认就是作用范围是action,也就是request中
     <s:property value="#newperson.name"/>
     ${requestScope.newperson.name}//注意el表示访问某个对象的属性方式
     ${requestScope.person.name}//可以用set的新名字去访问,也可以用旧的名字去访问。
url

url 标签用于生成一个URL 地址,可以通过为url 标签指定param子元素,从而向指定URL 发送请求参数。

  • action: 这是一个可选属性,指定生成URL 的地址为哪个Action,如果Action 不提供,就使用value 作为URL
    的地址值。要想跳转实际你定义的action,你需要把Struts.xml注册的action的name,填写在这。
  • anchor: 这是一个可选属性,指定URL 的锚点。
  • encode: 这是一个可选属性,指定是否需要对参数进行编码,默认是true.
  • escapeAmp: 这是一个可选参数,指定是否需要对&符号进行编码,默认是true。
  • forceAddSchemeHostAndPort: 这是一个可选参数,指定是否需要在URL
    对应的地址里强制添加scheme、主机和端口。
  • includeContext: 这是一个可选属性,指定是否需要将当前上下文包含在URL 地址中。
  • includeParams :这是一个可选属性, 该属性指定是否包含请求参数,该属性的属性值只能为none、get
    或者all。该属性值默认是get。
    属性值为get时,该url会将访问其所在jsp的的请求的所有get方法的参数添加到自身来。
    属性值为all时更是将get和post的的参数值全部添加到自身来。
    一般我们并不需要额外的参数,所以定义为none。
  • method: 这是一个可选属性,该属性指定Action 的方法。当我们用Action 来生成URL时,如果指定了该属性,则URL将链接到指定Action 的特定方法。要想跳转实际你定义的action,你需要把Struts.xml注册的action的name,填写在这。
  • namespace: 这是一个可选属性,该属性指定命名空间。当我们用Action 来生成URL 时,如果指定了该属性,则URL
    将链接到此namespace 的指定Action 处。
  • portletMode: 这是一个可选属性,指定结果页面的portlet 模式。
  • scheme : 这是一个可选属性,用于设置scheme 属性。
  • value: 这是一个可选属性,指定生成URL 的地址值,如果value 不提供就用action 属性指定的Action 作为URL
    地址。
  • var: 这是一个可选属性,如果指定了该属性,将会把该链接值放入Struts 2 的ValueStack中。该属性可用id
    代替,但l推荐使用var。
  • windowState: 这是一个可选属性,指定结果页面的portlet 的窗口状态。
  <s:url action="laoqiang">
  <s:param name="name" value="'helloword'"/> /StrutsTag/laoqiang.action?name=helloword
  </s:url>
  </br>
  <s:url value="laoqiang">
  <s:param name="name" value="'helloword'"/>laoqiang?name=helloword 根据这个你应该看出value和action都是作为地址值,但是有所不同
  </s:url>
  </br>
  <s:url>
  <s:param name="name" value="'helloword'"/>/StrutsTag/index.jsp?name=helloword
  </s:url>
  </br>
  <a href="<s:url includeParams="get" method="execute1" action="tag2" forceAddSchemeHostAndPort="true"/>"> fsdfdsfs</a>
  //我们通过<s:url/>来创造一个url,放到<a href></a>就可以跳转了
property

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

  • default: 这是一个可选属性,如果需要输出的属性值为null,则显示default 属性指定的值。

Struts 2的模板和主题

对于一个JSP 页面里包含的UI 标签而言,既可以直接设置该UI 标签需要使用的模板, 也可以设置该UI 标签使用的主题。实际上,对于界面开发者而言,并不推荐直接设置模板属性。因为模板是以主题的形式组织在一起的,界面开发者应该选择特定主题,而不是强制使用特定模板来表现一个UI标签。模板是一个UI 标签的外在表示形式。

主题是模板的组织形式,模板被包装在主题里面,对于开发者应该是透明的。当需要使用特定模板来表现某个UI 标签时,应让主题来负责模板的加载。

设置主题方式
  • 通过设定特定UI 标签上的theme 属性来指定主题。
  • 通过设定特定UI 标签外围的Form 标签的theme 属性来指定主题。
  • 通过取得page 会话范围内以theme 为名称的属性来确定主题。
  • 通过取得session 会话范围内的命名为theme 的属性来确定主题。
  • 通过取得application 会话范围内的命名为theme 的属性来确定主题。
  • 通过设置名为struts.ui.theme 的常量(默认值是xhtml) 来确定默认主题,该常量可以在struts.properties
    文件或者struts.xml 文件中确定。

上面的几种指定特定UI 标签主题的方式,它们是有着不同优先级的,排在前面的方式会覆盖排在后面的方式。例如,
我们通过特定UI 标签上的theme 属性指定了该标签的主题,那么后面指定的主题将不会起作用。

Struts 2 元素属性

JavaScript 拥有属性

这里写图片描述

这里写图片描述

鼠标悬停的通用属性

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

css设置属性

这里写图片描述

这里写图片描述

表单元素的name于value属性

每一个表单元素,都会映射成一个Action的属性,所以在使用的一定要保证表单元素的name属性值和对应Action的属性值一致,而一旦Action被实例化之后,Action的属性值就是表单元素的value。

表单元素

  • checkboxlist
    checkboxlist 标签可以一次创建多个复选框,用于同时生成多个的HTML 标签。它根据list 属性指定的集合来生成多个复选框,因此,使用该标签指定一个list 属性。

listKey: 该属性指定集合元素中的某个属性(例如集合元素为Person 实例,指定Person 实例的name 属性) 作为复选框的value.如果集合是Map,则可以使用key 和value 值指定Map 对象的key 和value 作为复选框的value.
listValue: 该属性指定集合元素中的某个属性(例如集合元素为Person 实例,指定Person实例的name 属性) 作为复选框的显示的选项名。如果集合是Map,则可以使用key 和value 值指定Map 对象的key 和value 作为复选框的标签。

      <s:checkboxlist name="a" list="{'laoqinag1','laoqiang2','laoqiang3'}" labelposition="top" />
      <s:checkboxlist name="b" list="#{'name':'laoqiang','age':23,'sex':'man'}" listKey="value" listValue="key"/>
      <s:bean name="com.example.test.service.BookService" var="bs"/>//通过var,将这个bean添加到StatckContext中
      <s:debug/>
      <s:checkboxlist name="c" list="#bs.book" listKey="name" listValue="price"/>

上面的集合创建,包括方法的调用都是基于OGNL的,OGNL访问方法,该方法名必须是get开头,调用的时候去除get,其他小写。如果你构建集合,不是一个对象,就没必要指定listKey,listValue,就比如第一种。

public class BookService {
   public Book[] getbook(){

       return new Book[]{
               new Book("laohe",21),
               new Book("laohe1",22),
               new Book("laohe2",23),
               new Book("laohe3",24),
       };

   }
}
  • doubleselect
    doubleselect 标签会生成个级联列表框(会生成两个下拉列框),当选择第一个下拉列表框时,第: 二个下拉列表框的内容会随之改变。
  <s:set var="bs11" value="#{'person': {'name','age','sex'},'teacher':{'laoqiang','teacherage'},'stuname':{'laopi','stuage'}}"/>
      <s:form>
      <s:doubleselect name ="d" list="{'laohe','laoqiang'}" doubleList="top=='laohe' ? {'laohe1','laohe2'} : {'laoqqiag1','laoqiang2'}" doubleName="e"/>
       //top 是第一个框中的选中的值,通过#bs11[top],map的键来获取。
      <s:doubleselect name="f" size="3" list="#bs11.keySet()" doubleList="#bs11[top]" doubleSize="3" doubleName="g"/>
      </s:form>

第一个下拉列表框只支持两组值,如果第一个下拉列表框包含三个或更多的值,这在默认情况下,
里的list 和doubleList 属性就不能这样直接设定了。我们采用的是map。

  • optiontransferselet
    optiontransferselet 会生成两个列表选择框,并生成系列的按钮用于控制各选项在两个下拉列表之间的移动、升降等。当提交该表单时,两个列表选择框对应的请求参数都会被提交。

这里写图片描述

这里写图片描述

 <s:optiontransferselect label="你喜欢的图书" name="optbook" leftTitle="中国图书" rightTitle="外国图书" list="{'java','wp','ss','po'}"
      multiple="true" addAllToLeftLabel="全部向左移动" selectAllLabel="全部选择" addAllToRightLabel="全部向右移动" doubleList="{'ppp','www',,'rrrr','tttt'}"
      doubleName="rightbook" doubleMultiple="true"
      />

这个标签都是封装好的,你直接对照属性使用就好。

  • select

该标签是生成一个下拉列表,基本用法和上面doubleselect 一致。

  • 列表内容

radio 标签的用法与checkboxlist 的用法几乎完全相同,一样可以指定label.list、listKey 和listValue等属性。与checkboxlist 唯一不同的是,checkboxlist 生成多个复选框,而radio 生成多个单选钮。

 <s:radio name="u" list="{'laohe','loaqinag','jiusjb','plkninb'}"/>
      //如果是普通的集合无需指定listkey和listvalue
  • optgroup
    optgroup 标签用于生成一个下拉列表框的选项组,因此,该标签必须放在selec…标签中使用。一个下拉列表框中可以包含多个选项组,因此可以在一个select…>标签中使用多个
<s:form>
      <s:select name="rr" list="{'laohe','laoqiang','laoki','laopo'}" >
      <s:optgroup label="选项组" list="#{'name':'laohe','sex':'man'}" listKey="key" listValue="value">
      </s:optgroup>
       <s:optgroup label="选项组1" list="#{'name1':'laohe1','sex1':'man1'}" listKey="key" listValue="value">
       //label属性是设置选项组名字的,不可以选中哦
      </s:optgroup>
      </s:select>
      </s:form>//下拉需要放在form中
  • token

    这是一个用于防止多次提交表单的标签,token标签能阻止多次提交表单的问题(避免刷新页面导致的多次提交)。如果需要该标签起作用,则应该在Struts2 的配置文件中启用TokenInterceptor拦截器或TokenSessionStorel nterceptor 拦截器。token 标签的实现原理是在表单中增加一个隐藏域,每次加载该页面时,该隐藏域的值都不相同。TokenInterceptor 拦截器则拦截所有用户请求,如果两次请求时该token 对应隐藏域的值相同(前一次提交时token 隐藏域的值保存session 里),则阻止表单提交。

默认情况下,token 标签生成的隐藏域的name 为struts.token.不要在表单中因此,另外再定义一个名为struts.token 的表单域。

<package name="default" extends="struts-default"   namespace="/">
    <action name="token" class="com.example.test.action.TestToken">
       <interceptor-ref name="defaultStack"/>
       <interceptor-ref name="token"/>
       <result name="invalid.token">/refresh.jsp</result>
       <result name="success">/show.jsp</result>
    </action>
</package>

上面配置文件中使用了2 个拦截器,其中defaultStack 是系统默认的拦截器栈。看似前面Struts2 应用都没有使用该拦截器,实际上该拦截器默认会生效; 此处因为显式使用了token 拦截器,所以必须显式配置使用defaultStack 拦截器,否则它不会默认生效。关于拦截器介绍请看下一章内容。另: 如果表单页没有使用标签,则千万不要使用token 拦截器,否则它将导致无法提交表单。

updownselect

updownselect 标签的用法非常类似于select 标签的用法,区别是该标签生成的列表框可以上下移动选项。因此使用该标签时,一样可以指定list.listKey 和listValue 等属性,这些属性的作用与使用select 标签时指定的list、listKey 和listValue 等属性完全相同。

<s:form>
      <s:updownselect name="a" labelposition="top" label="请选择" moveUpLabel="向上移动" moveDownLabel="向下移动" list="{'laoqiang','laoqiang2','laoqiang3'}"/>
      <s:updownselect name="b" labelposition="top" label="请选择2" moveUpLabel="向上移动" emptyOption="true" moveDownLabel="向下移动" list="#{'name':'laohe','age':'23','sex':'man'}" listKey="key" listValue="value"/>
      <s:bean name="com.example.test.service.BookService" var="bs2"></s:bean>
      <s:updownselect name="c" labelposition="top" label="请选择3" moveUpLabel="向上移动" emptyOption="true" moveDownLabel="向下移动" list="#bs2.book" listKey="key" listValue="value"/>
      </s:form>

注意在使用StackValue中的对象实例作为list集合是不需要加{ }的,加{ }的OGNL表达式构造的集合。
emptyOption 在列表构造一个空的选项。

非表单标签

非表单标签主要用于在页面中生成一些非表单的可视化元素,例如Tab 页面、输出HTML页面的树形结构等。当然,非表单标签也包含在页面中显示Action 里封装的信息。

  • actionerror: 如果Action 实例的getActionErrors()方法返回不为null,则该标签负责输出该方法返回的系列错误。
  • actionmessage: 如果Action实例的getActionMessages()方法返回不为null,则该标签负责输出该方法返回的系列消息。
  • component: 使用此标签可以生成一个自定义组件。
  • fielderror: 如果Action 实例存在表单域的类型转换错误、校验错误,该标签则负责输出这些。
public class TestActionMessage extends ActionSupport {
    @Override
    public String execute() throws Exception {
        // TODO Auto-generated method stub

        addActionError("错误信息1");//可以看出添加信息就类似在集合中添加数据,在显示的时候,集合是通过有序列表进行显示。
        addActionError("错误信息2");
        addActionMessage("这是普通消息1");
        addActionMessage("这是普通消息2");

        return SUCCESS;
    }

    @Override
    public Collection<String> getActionErrors() {
        // TODO Auto-generated method stub
        return super.getActionErrors();
    }

    @Override
    public Collection<String> getActionMessages() {
        // TODO Auto-generated method stub
        return super.getActionMessages();
    }
}

配置action

 <action name="testmessage" class="com.example.test.action.TestActionMessage">
       <result name="success">/show.jsp</result>//name属性要和配置的actionname一致。
    </action>
    <s:action name="testmessage" executeResult="true" namespace="/"></s:action>//executeResult是action1执行结果包含在本页面中。
    action中ignoreContextParam:可选参数,指定该页面的请求参数是否需要传入调用的Action中,默认值是false,
    namespace 是防止你在配置多个package下的action重名问题。

component

component 标签可用于创建自定义视图组件,这是一个非常灵活的用法。如果开发者经常需要使用某个效果片段, 就可以考虑将这个效果片段定义成一个视图组件,然后在页面中使用component 标签来使用该自定义组件。

  • theme : 自定义组件所使用的主题, 如果不指定该属性, 则默认使用xhtml 主题。
  • templateDir: 指定自定义组件的主题目录,如果不指定, 则默认使用系统的主题目录, 即template 目录。
  • template: 指定自定义组件所使用的模板。

    除此之外,还可以在cmponent 标签内使用param子标签,子标签表示向该标签模板中传入额外的参数。如果希望在模板中取得该参数,总是采用: parameters.paramNam p a r a m e t e r s . p a r a m N a m 或 者 parameters[param形式。

下面我们先来说第一种模板,采用默认系统的主题目录,系统的模板文件你可以把struts-core 核心的jar解压,就可以看到在一个template/xhtml (xhtml 是代表的是主题)

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@taglib prefix="s"  uri="/struts-tags"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<div>
<s:debug/>
<s:select list="parameters.list1">//这个下拉列表的数据是通过list1来传进来的
</s:select>
</div>
    <s:component  template="MyTemplate.jsp" >
    <s:param name="list1" value="{'laoeh2','laohe3','laohe4'}"/>
    </s:component>

在这里我特别需要说的就是你编写的目录路径,必须和系统的那个命名一致,且必须放置在webroot下,也就是根目录,绝对不可以是其他路径,否则web是加载不到模板文件,因为采用系统的主题,它会到指定的template/xhtml下检索。

这里写图片描述

如果采用自定义主题,那就easy多了。

     <s:component  templateDir="templateDir" theme="customtheme" template="MyAnotherTemplate.jsp" >
    <s:param name="list" value="{'laoeh6','laohe8','laohe9'}"/>
    </s:component>
<div>
<select>
<s:iterator value="%{top.parameters.list}">//因为参数会添加到栈值中,top取栈顶元素
<option><s:property/></option>
</s:iterator>
</select>
</div>
  <s:component  templateDir="templateDir" theme="customtheme" template="MyAnotherTemplate.jsp" >
    <s:param name="list" value="{'laoeh6','laohe8','laohe9'}"/>
    </s:component>

这回你把模板文件随便放在哪多行,但是要在webroot这个根目录下,其他路径下,需要添加对应的路径。

这里写图片描述

需要注意在使用自定义模板的时候,需要创建两个文件夹,一个对应templateDir,子文件夹对应theme。

可以看出这种方式灵活,但是也有缺点,就是使用自定义主题,原有的struts的主题,路径都不会加载,在上面的代码中无法使用了。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

venus321

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值