您的位置:首页 > 编程语言 > Java开发

【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

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 非表单标签

actionerror

actionmessage

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息