Struts2提供了级联下拉选择框doubleselect标签,这对简化诸如省份/城市这样的典型需求的操作是大有好处的 ,本例是生成“部门->员工”的级联菜单。
<s:form action= "doubleSelectPost" name= "form1">
<s:doubleselect
formName= "form1"
label= "业务员"
list= "#request.map.keySet()"
name= "dptId"
id= "comboId"
listKey= "dptId"
listValue= "dptName"
doubleName= "eplId"
doubleId= "comboDoubleId"
doubleList= "#request.map[top]"
doubleListKey= "eplId"
doubleListValue= "userName" />
</s:form>
说明:
formName: 对应的表单名称。
label: 该级联下拉列表的标签。
name: 第一个下拉列表的名称。name="dptId"指明了第一个下拉列表名称为dptId。
id: 第一个下拉列表的id名称。
list: 指定用于输出第一个下拉列表框中选项的集合。本示例 list="#request.map.keySet()" 是将map的键(即部门)作为第一个下拉列表选项。
listKey: 指定集合元素中的某个属性作为第一个下拉列表框的value。listKey="dptId"是将部门id作为第一个下拉列表的值,在提交该表单时,参数名就是depId,值为listKey的值。如“dptId=1”
listValue:指定集合元素中的某个属性作为第一个下拉框的标签。listValue="dptName" 用部门名称作为标签,即下拉列表显示出来的值。
doubleName: 第二个下拉列表的名称。
doubleId: 第二个下拉列表的id名称。
doubleList: 指定用于输出第二个下拉列表框中选项的集合。本示例 #request.map[top] 是将map的值(即员工)作为第二个下拉列表选项。
此处要注意的是top的用法,top代表的就是list当前选中的对象,
doubleListKey: 指定集合元素中的某个属性作为第二个下拉列表框的value。doubleListKey="eplId"是将员工id作为第二个下拉列表的值。
doubleListValue: 指定集合元素中的某个属性作为第二个下拉框的标签。doubleListValue="userName" 用员工名称作为标签。
可以看到,生成出来的级联下拉列表是分行的,如果不需要分行,可以怎么做呢?
以下介绍一个简单的方法,就是在<s:form>标签外包含标签:
<div class= "doubleselect"><s:form>。。。</s:form></div>
<STYLE type="text/css">
.doubleselect br{
display:none;
}
</STYLE>
(1)
append标签用于将多个集合对象拼接起来,组成一个新的集合,通过这种拼接,从而允许通过一个<s:iterator../>标签就完成多个集合的迭代.
使用<s:append../>标签需要指定一个id属性,该属性确定拼接生成的新集合名称.<s:append../>标签接受多个<s:param.../>子标签,每个子标签指定一个集合,append标签负责将多个集合拼接成一个集合.
例如页面接受了几个集合对象:list1,list2,list3
在页面中可以这样写:
<%
list1=new ArrayList();
list1.add("a");
list1.add("b");
list2=new ArrayList();
list2.add("A");
list2.add("B");
%>
<s:append id="newList">
<s:param value="list1"/>
<s:param value="list2"/>
<s:param value="list3"/>
</s:append>
<s:iterator value="#newList">
</s:iterator>
这样输出将会是:a,b,A,B.
(2)
merge标签,其用法与append一样.只是对集合合并后的次序不一样.其输出是:a,A,b,B.
(3)
token标签
作用:struts2.0使用拦截器来检查表单是否重复提交.它采用同步令牌方式来实现对表单重复提交的判断。
理解:
token标签的实现原理:
创建一个新的令牌值,并用所指定的令牌名把令牌保存到session中,这个令牌值是随机产生且加密的序列,所以不会重复。
1、JSP使用<s:token/>标签的时候,Struts2会建立一个GUID(全局唯一的字符串)放在session中,并且会成为一个hidden放在form中,若查看页面源码,可见如下:
<input type="hidden" name="struts.token.name" value="struts.token"/>
<input type="hidden" name="struts.token" value="BXPNNDG6BB11ZXHPI4E106CZ5K7VNMHR"/>
2、token拦截器会判断客户端form提交的token和session中保存的session是否equals。如果equals则执行Action。否则拦截器直接返回invaid.token结果,Action对应的方法也不会执行
实例如下:
1、使用Struts2的表单标签,其中需要增加token标签。如下:
<%@ taglib uri="/struts-tags" prefix="s" %>
……
<s:form action="page1" theme="simple">
<s:datetimepicker name="order.date" label="购买日期" toggleType="explode" value="today"/><br/>
<s:token/>
<s:reset/><s:submit/>
</s:form>
2、在struts配置文件中增加token拦截器。如下:
<struts>
<package name="lee" extends="struts-default">
<action name="page1" class="org.bruce.Page1">
<interceptor-ref name="defaultStack" /> //相应添加处一
<interceptor-ref name="token" /> //相应添加处二--添加token拦截器
<result>/page1.jsp</result>
<result name="invalid.token">/page1error.jsp</result> //相应添加处三--定义重复提交的输出页面
</action>
</package>
</struts>
注意,需要name为invaid.token的result。这是当拦截器判断是重复提交的时候,会转向的结果。
3.
在page1error.jsp页面中添加:
invaid.token页面打印错误信息,一样可以使用struts标签。如下:
<s:actionerror/>
(4)
debug标签:
debug标签主要用于辅助测试,它在页面上生成一个超链接,通过该链接可以查看ValueStack和Stack Context 中的所有值信息。
在页面上增加<s:debug/>标签,通过debug标签,可以看的系统中ValueStack离得全部信息,并可以看到Stack Context中的属性。
(1)
checkboxlist标签的使用
实例:
<!-- 使用简单集合来生成多个复选框 -->
<s:checkboxlist name="a" label="请选择您喜欢的图书" labelposition="top"
list="{'Spring2.0宝典' , '轻量级J2EE企业应用实战' , '基于J2EE的Ajax宝典'}"/>
<!-- 使用简单Map对象来生成多个复选框 -->
<s:checkboxlist name="b" label="请选择您想选择出版日期" labelposition="top"
list="#{'Spring2.0宝典':'2006年10月' , '轻量级J2EE企业应用实战':'2007月4月' , '基于J2EE
的Ajax宝典':'2007年6月'}"
listKey="key"
listValue="value"/>
checkboxllist标签可以一次创建多个复选框,相当于多个<input type="checkbox"标签> ,它根据list属性指定的集合来生成多个复选框。
注意:
checkboxllist标签有两个属性,listKey和listValue,他们代表了list中元素的某个属性,默认情况下 lisKey="key"(这里的key代表map中的key值,也是会传给strut2的值),listValue="value"(这里的value 代表map中的value值,他会在页面中显示出来,提交表单时,并不能被struts取得)。
public class User {
private String username;
private String password;
public User(String username,String password) {
this.username = username;
this.password = password;
}
。。。。省略POJO
}
public class UserService {
public User[] getRyan(){
return new User[]{
new User("ryan","ryanchen"),
new User("zhengyao","YOYO"),
new User("boys","girls")
};
}
}
在jsp页面中使用:
<s:bean name="com.yan.test.UserService" id="sds"/>
<s:checkboxlist name="sdfsd" list="#sds.ryan"
listKey="username"
listValue="password">
</s:checkboxlist>
浏览该页面:
口ryanchen 口YOYO 口girls
(2)
(combobox)
Struts2中的combobox类似HTML中的select,一个组合框,用起来很简单。
而doubleselect的功能倒是很强大,就是我们传说中的级联菜单,记得用JavaScript写也要写一会。
先看combobox.jsp:
<%@ page language= "java" import= "java.util.*" pageEncoding= "UTF-8"%>
<%@ taglib prefix= "s" uri= "/struts-tags"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head></head>
<body>
<s:form>
<!-- 直接指定list集合里面的值-->
<s:combobox label="选择你喜欢的颜色" name="colorNames"
headerValue="------请选择------" headerKey="1"
list="{'红','橙','黄','绿','青','蓝','紫'}" />
<!-- 动态绑定list集合里面的值 -->
<s:combobox label="选择你喜欢的颜色" name="colorName"
headerValue="------请选择------" headerKey="1" list="colorname" />
</s:form>
</body>
</html>
因为动态绑定,再增加一个ComboboxAction.java:
package com.kalman03.action;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
public class ComboboxAction extends ActionSupport {
private List colorname;
public List getColorname() {
return colorname;
}
public void setColorname(List colorname) {
this.colorname = colorname;
}
public String execute() throws Exception {
colorname = new ArrayList();
//colorname的选项当然是来自数据库
colorname.add( "红");
colorname.add( "橙");
colorname.add( "黄");
colorname.add( "绿");
colorname.add( "青");
colorname.add( "蓝");
colorname.add( "紫");
this.setColorname(colorname);
return SUCCESS;
}
}
配置struts.xml:
<
action
name
="comboboxtag"
class
="com.kalman03.action.ComboboxAction"
>
<
result
>
/combobox.jsp
</
result
>
</
action
>
看效果:
(3)
Struts2中的
datetimepicker是一个时间选择器,个人觉得是一个非常方便的标签,我们知道用JavaScript代码实现一个日期选择器那要写好长以段代码,而Struts2内置的这个datetimepicker标签却帮我们摆脱了长长的JavaScript的噩梦。来看一下就知道了:
datetimepicker.jsp:
<%
@ page language
=
"
java
"
import
=
"
java.util.*
"
pageEncoding
=
"
UTF-8
"
%>
<%
@ taglib prefix
=
"
s
"
uri
=
"
/struts-tags
"
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
s:head
theme
="simple"
/>
<!--
上面这个head标签必须要加,至于设置哪种主题没有限制,根据自己开发的需要
-->
<!--
当没有加的时候就没有显示,这是为什么?我学习的时候不懂,谁看到了帮我解释下
-->
<
body
>
<
s:datetimepicker
value
="today"
name
="getdate"
label
="时间选择器"
></
s:datetimepicker
>
</
body
>
</
html
>
可以看到很漂亮的效果:
当然我们可以格式化日期格式,一些其他的处理可以根据需要在action里面进行处理。来看一个初始化时间为2008-08-08,按照年月日显示的日期选择器:
增加下列代码到上面的JSP里面:
<
s:datetimepicker
name
="hopedate"
label
="year-month-date"
displayFormat
="yyyy-MM-dd"
/>
也可:
<
s:datetimepicker
name
="hopedate"
label
="year-month-date"
displayFormat
="yyyy年-MM月-dd日"
/>
增加一个DatetimepickerAction.java:
package
com.kalman03.action;
import
java.util.Date;
import
com.opensymphony.xwork2.ActionSupport;
public
class
DatetimepickerAction
extends
ActionSupport {
private
Date hopedate;
public
Date getHopedate() {
return
hopedate;
}
public
void
setHopedate(Date hopedate) {
this
.hopedate
=
hopedate;
}
@Override
public
String execute()
throws
Exception {
this
.setHopedate(
new
Date(
"
Aug 08,2008 12:00:00 AM
"
));
return
SUCCESS;
}
}
配置struts.xml里面的映射关系:
<
action
name
="datetimepickertag"
class
="com.kalman03.action.DatetimepickerAction"
>
<
result
>
/datetimepicker.jsp
</
result
>
</
action
>
到此结束可以在浏览器输入: http://localhost:8080/test/datetimepickertag.action得到格式化后的效果:
(4)
(checkbox/checkboxlist )
其中的name,即是Action中对应的对象,value即是要传到action的值.
checkbox.jsp:
<%
@ page language
=
"
java
"
import
=
"
java.util.*
"
pageEncoding
=
"
UTF-8
"
%>
<%
@ taglib prefix
=
"
s
"
uri
=
"
/struts-tags
"
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
head
>
</
head
>
<
body
>
<
s:checkbox
label
="足球"
name
="checkbox"
value
="football"
fieldValue
="true"
/>
<!--
上面一行代码等同下面一行HTML代码,属性都很简单不再介绍
-->
<
input
type
="checkbox"
name
="checkbox"
value
="football"
/>
足球
</
body
>
</
html
>
效果图:
再看checkboxlist.jsp:
checkboxlist的list内容,直接在Action中的List变量中定义.这样,要显示内容,须先到Action,再从action到jsp.
<%
@ page language
=
"
java
"
import
=
"
java.util.*
"
pageEncoding
=
"
UTF-8
"
%>
<%
@ taglib prefix
=
"
s
"
uri
=
"
/struts-tags
"
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
head
>
<
title
>
struts2
</
title
>
</
head
>
<
body
>
<
s:checkboxlist
list
="foodList"
name
="food"
label
="food"
/>
<
br
>
<
s:checkboxlist
list
="hobbyList"
name
="hobby"
label
="hobby"
/>
</
body
>
</
html
>
增加list集合里面映射类CheckboxlistAction.java:
package
com.kalman03.action;
import
java.util.ArrayList;
import
java.util.List;
import
com.opensymphony.xwork2.ActionSupport;
/**
* @FileName CheckboxlistAction.java
*
* @Author kalman03
*
*/
public
class
CheckboxlistAction
extends
ActionSupport {
private
List foodList;
private
List hobbyList;
public
List getFoodList() {
return
foodList;
}
public
List getHobbyList() {
return
hobbyList;
}
@Override
public
String execute()
throws
Exception {
foodList
=
new
ArrayList
<
String
>
();
foodList.add(
"
milk
"
);
foodList.add(
"
rice
"
);
foodList.add(
"
noodles
"
);
hobbyList
=
new
ArrayList
<
String
>
();
hobbyList.add(
"
football
"
);
hobbyList.add(
"
basketball
"
);
hobbyList.add(
"
volleyball
"
);
return
SUCCESS;
}
}
在struts.xml里面配置好映射,即增加下列代码:
<
action
name
="checkboxlisttag"
class
="com.kalman03.action.CheckboxlistAction"
>
<
result
>
/checkboxlist.jsp
</
result
>
</
action
>
ok,在浏览器中输入:http://localhost:8080/test/checkboxlisttag.action,可以看到结果:
(5)
(autocompleter )
个人感觉autocompleter用处比较明显,就是一个智能感知。更体现了struts2的灵活性。看实例:
autocompletertag.jsp:
<%
@ page language
=
"
java
"
import
=
"
java.util.*
"
pageEncoding
=
"
UTF-8
"
%>
<%
@ taglib prefix
=
"
s
"
uri
=
"
/struts-tags
"
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
s:head
theme
="ajax"
/>
<
body
>
<
s:autocompleter
name
="test"
list
="{'湖南','上海','北京','广东'}"
autoComplete
="false"
/>
<
s:autocompleter
list
="provice"
name
="provice"
/>
</
body
>
</
html
>
在src目录的com.kalman03.action包下建一个AutocompleterAction.java:
package
com.kalman03.action;
import
java.util.ArrayList;
import
java.util.List;
import
com.opensymphony.xwork2.ActionSupport;
/**
* @FileName AutocompleterAction.java
*
* @Author kalman03
*
*/
public
class
AutocompleterAction
extends
ActionSupport {
private
List provice;
@Override
public
String execute()
throws
Exception {
List arl
=
new
ArrayList();
arl.add(
"
湖南
"
);
arl.add(
"
湖北
"
);
arl.add(
"
上海
"
);
arl.add(
"
北京
"
);
arl.add(
"
天津
"
);
arl.add(
"
广东
"
);
this
.setProvice(arl);
return
SUCCESS;
}
public
List getProvice() {
return
this
.provice;
}
public
void
setProvice(List provice) {
this
.provice
=
provice;
}
}
在struts.xml内增加代码:
<
action
name
="autocompletertag"
class
="com.kalman03.action.AutocompleterAction"
>
<
result
>
/autocompletertag.jsp
</
result
>
</
action
>
OK,在浏览器输入http://localhost:8080/myweb/autocompletertag.action,可以看到效果:
注意:<s:head theme="ajax" />我们在JSP里面增加一句这样的话,关于struts2标签的主题日后讲解,这里顺便提下,当theme为simple时,那么autocompleter标签相当于HTML中的ComboBox,当且theme为ajax时,list才能从action里面获得动态的值。