控制标签
使用Struts2标签必须先导入标签库,在页面使用如下代码导入Struts2标签:
<%@taglib prefix="s" uri="/struts-tags"%>
if/elseif/else标签:
<s:set name="age" value="29">
<s:if test="#age>60">
老年人
</s:if>
<s:elseif test="#age>35">
中年人
</s:elseif>
<s:elseif test="#age>15">
青年人
</s:elseif>
<s:else>
少年儿童
</s:else>
Action提示信息
actionerror和actionmessage标签:
这两个标签都是用来输出Action实例里封装的信息,actionerror负责输出Action实例的getActionErrors()方法的返回值。actionmessage负责返回Action实例的getActionMessages()方法的返回值。
Action代码:
public Class TestAction{
public String execute(){
addActionError("出错了!");
addActionMessage("请联系系统管理员!");
}
}
在页面中使用标签输出:
<s:actionerror/>
<s:actionmessage/>
表单标签
Struts2提供了很多表单标签,大部分表单标签和HTML表单标签之间有一一对应的关系,这里只介绍一些比较特殊的表单标签。对于表单标签而言,name和value存在一个特殊的关系,每个表单元素会被映射成Action属性。
使用Struts2标签必须先导入标签库,在页面使用如下代码导入Struts2标签:
<%@taglib prefix="s" uri="/struts-tags"%>
textfield标签:
<s:textfield name="person.firstName"/>
checkboxlist标签:
使用简单集合来生成多个复选框
<s:checkboxlist name="a" lable="请选择你喜欢的图书" labelposition="top" list="{'Java编程思想','J2EE企业应用实战'}"/>
使用简单Map对象来生成多个复选框
<s:checkboxlist name="b" label="请选择你喜欢的图书" labelposition="top" list="{'Java编程思想':'2012年8月','J2EE企业应用实战':'2012年9月'}" listKey="key" listValue="value"/>
使用创建的放有多个对象的JavaBean对象来生成多个复选框
<s:bean name="com.service.BookService" id="bs"/>
<s:checkboxlist name="b" label="请选择你喜欢的图书" labelposition="top" list="#bs" listKey="author" listValue="name"/>
public class BookService{
public Book[]getBooks(){
return new Book[]{
new Book("Java编程思想","李刚");
new Book("J2EE企业应用实战","李刚");
};
}
}
public class Book{
private String name;
private String author;
public Book(String name,String author){
this.name=name;
this.author=author;
}
//getter&setter...
}
select标签:
使用集合来生成下拉选择框
<s:select name="a" lable="请选择你喜欢的图书" lableposition="top" multiple="true" list="{'Java编程思想','J2EE企业应用实战'}" />
使用简单Map对象来生成下拉选择框
<s:select name="b" lable="请选择你喜欢的图书" lableposition="top" multiple="true" list="#{'Java编程思想':'2012年8月','J2EE企业应用实战':'2012年9月'}" listKey="key" listValue="value"/>
属性说明:
multiple:设置该列表框是否允许多选
listKey:指定集合中的某个元素作为复选框的value
listValue:指定集合中的某个元素作为复选框的标签
使用集合里放多个JavaBean实例来生成下拉选择框
<s:bean name="com.service.BookService" id="bs"/>
<s:select name="b" lable="请选择你喜欢的图书" labelposition="top" multiple="true" list="#bs.books" listKey="author" listValue="name"/>
radio标签:
使用集合来生成单选框
<s:radio name="a" lable="请选择你喜欢的图书" lableposition="top" multiple="true" list="{'Java编程思想','J2EE企业应用实战'}" />
使用简单Map对象来生成单选框
<s:radio name="b" lable="请选择你喜欢的图书" lableposition="top" multiple="true" list="#{'Java编程思想':'2012年8月','J2EE企业应用实战':'2012年9月'}" listKey="key" listValue="value"/>
使用集合里放多个JavaBean实例来生成单选框
<s:bean name="com.service.BookService" id="bs"/>
<s:radio name="c" lable="请选择你喜欢的图书" labelposition="top" multiple="true" list="#bs.books" listKey="author" listValue="name"/>
optgroup标签:
<s:optgroup lable="请选择你喜欢的图书" list="#{'Java编程思想':'2012年8月'}" listKey="value" listValue="key"/>
<s:optgroup lable="请选择你喜欢的图书" list="#{'J2EE企业应用实战':'2012年9月'}" listKey="value" listValue="key"/>
token标签:
这是一个防止多次提交表单的标签,如果需要该标签起作用,则应该在Struts2的配置文件中启用TokenInterceptor拦截器或TokenSessionStoreInterceptor拦截器。
token的实现原理:在表单中增加一个隐藏域,每次加载页面时,该隐藏域的值都不同,而TokenInterceptor则拦截所有的用户请求,如果两次请求时该token对应隐藏域的值相同,则阻止表
单提交。
<s:token />
doubleselect标签:
doubleselect标签会生成一个级联列表框,当选择第一个下拉列表框时,第二个下拉列表框的内容会随之而改变。
<s:doubleselect lable="请选择你喜欢的图书"
name="author"
list="{'李刚','David'}"
doubleList="top=='李刚'?{'Struts2权威指南','轻量级Java EE企业应用实战'}:{'Java编程思想','23种设计模式'}"/>
使用Map对象来创建doubleselect
<s:set name="bs" value="#{'李刚':{'Struts2权威指南','轻量级Java EE企业应用实战'},'David':{'Java编程思想','23种设计模式'}}"/>
<s:doubleselect lable="请选择你喜欢的图书"
size="3"
name="author"
list="#bs[top]"
doubleSize="3"
doubleName="book"/>
optiontransferselect标签:
optiontransferselect标签会生成两个列表选择框,并生成系列的按钮来控制各选项在两个下拉列表之间的移动、升降。当提交表单时,两个列表选择框对应的请求参数都会被提交。
<s:optiontransferselect
lable="请选择你喜欢的图书"
name="cnbook"
leftTitle="中文图书"
rightTitle="外文图书"
list="{'Struts2权威指南','Java编程思想'}"
multiple="true"
addToLeftLable="向左移动"
selectAllLable="全部选择"
addAllToRightLable="全部右移"
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"
/>
属性说明:
list:设置第一个下拉列表选择框的集合
listKey:设置第一个下拉列表选择框的value属性
listValue:设置第一下下拉列表选择框的lable属性
doubleList:设置第二个下拉列表选择框的集合
doubleListKey:设置第二个下拉列表选择框的value属性
doubleListValue:设置第二个下拉列表选择框的lable属性
doubleMultiple:设置第二个下拉列表选择框是否允许多选
updownselect标签:
使用简单集合来生成可上下移动选项的下拉选择框
<s:updownselect name="a" label="请选择你喜欢的图书"
lableposition="top"
moveUpLable="向上移动"
list="{'Struts2权威指南','Java编程思想'}"/>
使用简单Map对象来生成可上下移动选项的下拉选择框
<s:updownselect name="b" lable="请选择你喜欢的图书"
lableposition="top"
moveDownLable="向下移动"
list="{'Struts2权威指南':'2012年8月','Java编程思想':'2012年9月'}"
listKey="key"
listValue="value"
emptyOption="true"
/>
使用集合里放多个JavaBean实例来生成可上下移动选项的下拉选择框
<s:bean name="com.service.BookService" id="bs"/>
<s:updownselect name="c" lable="请选择你喜欢的图书"
lableposition="top"
selectAllLable="全部选择"
list="#bs.books"
listKey="author"
listValue="name"
multiple="true"
/>
数据标签
bean标签:
作用:用于创建一个JavaBean实例
例子:
<s:bean name="com.dto.Person">
//设置JavaBean的属性
<s:param name="name" value="Jay"/>
<s:param name="age" value="29"/>
//输出显示
姓名:<s:property name="name"/>
年龄:<s:property name="age"/>
</s:bean>
在<s:bean.../>标签外访问JavaBean
例子:
<s:bean name="com.dto.Person" var="p">
//设置JavaBean的属性
<s:param name="name" value="Jay"/>
<s:param name="age" value="29"/>
</s:bean>
//输出显示
姓名:<s:property value="#p.name"/>
年龄:<s:property value="#p.age"/>
说明:为bean标签指定var属性,意味着将该JavaBean放置到Stack Context中,因此即使不在<s:bean.../>内,也可以通过该var属性来访问该JavaBean。
date日期标签:
日期的格式化输出
例子:
<s:bean var="now" name="java.util.Date">
<s:date name="#now" formar="yyyy/mm/dd"/>
</s:bean>
将格式化后的日期值字符串放入StackContext中并放入requestScope中,该属性也可用id代替,但推荐使用var
例子:
<s:date name="#now" var="abc"/>
<s:property value="abc"/>
debug标签:
该标签主要用来调试,它在页面生成一个超级链接,通过该链接可以查看到ValueStack和Stack Context中所有值信息,该标签只有一个
id属性,没有太大的意义。
例子:
<s:debug id="deb">
include标签:
该标签用于将一个Jsp页面或者一个Servlet包含到本页面中
例子:
<s:include value="included-file.jsp">
<!--传入参数到包含的Jsp或者Servlet-->
<s:param name="author" value="admin">
</s:include>
集合操作
判断元素是否在指定集合中:
in:判断元素是否在指定集合中
例子:
<s:if test="'foo' in {'foo','bar'}">
foo包含在集合中
</s:if>
<s:else>
foo不包含在集合中
</s:else>
not in: 判断元素是否不在指定集合中
例子:
<s:if test="'foo' not in{'foo','bar'}">
foo不包含在集合中
</s:if>
<s:else>
foo包含在集合中
</s:else>
取集合中指定条件的子集合:
?:取出所有符合选择逻辑的元素
^:取出符合选择逻辑的第一个元素
$:取出符合选择逻辑的最后一个元素
例子:
person.relatives.{? #this.gender=='male'}
取出person的所有性别为male的集合
对集合进行迭代:
Iterator:迭代输出List
例子:
<table>
<s:iterator value="{'Jay', 'Jolin', 'Andy'}" id="name" status="st">
<tr>
<td>
<s:property value="#st.index"/>
</td>
<td>
<s:property value="name"/>
</td>
</tr>
</s:iterator>
</table>
Iterator:迭代输出Map
例子:
<table>
<s:iterator value="#{'Jay' : '周杰伦', 'Jolin' : '蔡依林', 'Andy' : '刘德华'}" id="score" status="st">
<tr>
<td>
<s:property value="key"/>
</td>
<td>
<s:property value="value"/>
</td>
</tr>
</s:iterator>
</table>
iterator标签中的其它方法:
getCount(): 返回当前迭代了几个元素
getIndex(): 返回当前被迭代元素的索引
isEven(): 返回当前元素被迭代元素的索引是否是偶数
isOdd(): 返回当前元素被迭代元素的索引是否是奇数
isFirst(): 返回当前被迭代元素是否是第一个元素
isLast(): 返回当前被迭代元素是否是最后一个元素
例子:
<table>
<s:iteraotr value="{'Jay','Jolin','Andy'}" 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>
Stack Context中的对象与访问
根对象的访问:
传统的OGNL表达式求值中,系统会假设只有一个根对象。如果系统的Stack Context中包含两个对象,foo和bar,它们在Context中的名字分别为foo和bar,并将foo设置为Context的根对象。
访问根对象foo的属性: #foo.blah或blah
访问其它对象: #bar.blah
如果要访问的属性属于根对象,则可以直接访问该属性,否则使用一个名作为前缀修饰属性。
Struts2提供的命名对象
Struts2使用标准的Context进行OGNL表达式语言求值,OGNL的*对象是一个Map类型实例对象Context,其根对象就是ValueStack。要访问ValueStack中的属性,可以通过以下方式:${bar}
Struts2提供了一些命名对象,但这些对象不是Stack Context的根对象,它们只是存在于Stack Context中,所以要访问这些对象时需要使用#前缀来指明。
(1).parameters对象:用于访问Http请求参数,如:#parameters.foo, #parameters['foo']。用于返回调用HttpServletRequest的getParameter("foo")的返回值。
(2).request对象:用于访问HttpServletRequest的属性。如:#request['foo'], #request.foo。用于返回调用HttpServletRequest的getAttribute("foot")的返回值。
(3).session对象:用于访问HttpSession的属性。如:#session['foo'], #session.foo。用于返回调用HttpSession的getAttribute("foo")的返回值。
(4).application对象:用于访问ServletContext的属性。如:#application['foo'], #application.foo。用于返回调用ServletContext的getAttribute("foo")的返回值。
(5).attr对象:该对象将依次搜索如下对象:PageContext, HttpServletRequest, HttpSession, ServletContext中的属性。
当系统创建的Action实例后,该Action实例已经被保存到ValueStack中,所以无需写#即可直接访问Action属性。
Stack Context中的对象:
Stack Context---ValueStack(根对象)
---parameters(命名对象)
---request(命名对象)
---session(命名对象)
---application(命名对象)
---attr(命名对象)
访问Stack Context的根对象的属性时可以省略对象名,访问其它命名对象时需要在对象名前添加#前缀。
JSTL标签
EL表达式
使用很简单,不用在JSP中写入支持标签的语句,直接可以拿来用。
${hello} 等同于 <%= request.getAttribute("hello") %>
EL表达式还支持四则运算,大小比较(返回true或false),为空验证(${empty hello},返回true或false),还支持如${group.name} ${map.key}返回相应的值
JSTL核心库 (c标签)
首先,你要把jar包引进去,这里有个问题,如果是struts1.3.10的话,其自带的jstl包是1.0版本,而1.0版本的jstl在2.0的JSP中,会有问题。所以要下个1.1以上版本的jstl包,下载地址在此:http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi
然后,在JSP中加入支持标签的语句,<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
⑴,c:out 就是做输出
<c:out value="${hello}"/> 等同于 ${hello}
<c:out value="${abc}" default="haha"/> 如果${abc}不存在,那么给一个初始值haha
String HTML = "<font color='red'>北京欢迎你</font>";
request.setAttribute("bj", HTML); action中把值送出来
<c:out value="${bj}" escapeXml="false"> escapeXml:是否脱离XML语法,不是的话,就还是按照HTML语法解析,输出结果:北京欢迎你
⑵,c:set , c:remove
c:set 等于在page级别,setAttribute一个值,在当前页面用c:out可以接收到,例如:
<c:set value="beckham" var="player"/>
c:remove就是把一个属性值从当前page中删了,例如:
<c:remove var="player"/>
⑶,c:if 就是个条件分支语句,只能表达出if,没有else
<c:if test="${1 < 2}" var="result">
1 < 2<br>
${result }<br>
</c:if>
输出结果:
1 < 2
true
⑷,c:choose,c:when,c:otherwise,其实也是个条件分支语句,不过这次可以形成if。。。else的组合了^_^
c:when就是if,c:otherwise就是else,要注意的是c:when,c:otherwise必须写在c:choose标签的里面
<c:choose>
<c:when test="${v1 < v2}">
v1 < v2<br>
</c:when>
<c:otherwise>
v1 > v2<br>
</c:otherwise>
</c:choose>
⑸,c:forEach, 就是个循环
<c:forEach items="${userList}" var="user"> ←这里的var相当于把一个对象Attribute取出来后,给这个对象起的名字(也就是这个对象的引用),下面就可以用这个引用来显示该对象的属性
<tr>
<td>${user.username }</td>
<td>${user.age }</td>
<td>${user.group.name }</td>
</tr>
</c:forEach>
输出结果如下
name age group
選手 0 20 AC milan
選手 1 21 AC milan
選手 2 22 AC milan
選手 3 23 AC milan
選手 4 24 AC milan
■ c:forEach中的varStatus属性 ,varStatus可以记录本次循环的一些信息,比如现在循环到第几次啦,就是vs.count ,下面这个例子,当循环进行到偶数次时,改变背景颜色为黄色
<c:forEach items="${userList}" varStatus="vs" var="user">
<c:choose>
<c:when test="${vs.count % 2 == 0}"> ←如果是偶数次,背景色变为黄色
<tr bgcolor="yellow">
</c:when>
<c:otherwise> ←如果步是偶数次,背景色不变
<tr>
</c:otherwise>
</c:choose>
<td>${user.username }</td>
<td>${user.age }</td>
<td>${user.group.name }</td>
</tr>
</c:forEach>
输出结果如下
name age group
選手 0 20 AC milan
選手 1 21 AC milan
選手 2 22 AC milan
選手 3 23 AC milan
選手 4 24 AC milan
■ c:forEach中的begin , end, step属性,begin:从哪里开始循环,end:到哪里结束,step:每次循环的步长
■ 可以用c:forEach接受的除了List还有Map,接受Map的时候还可以分别取出key和value的值,例子:
<c:forEach items="${map}" var="v" >
${v.key } = ${v.value }<br>
</c:forEach>
⑹,c:forTokens 用于有分隔符字符串的迭代,delims属性用来设置分隔符的类型(逗号啦,斜杠啦),看例子:
action中的送值
request.setAttribute("forTokens","1,2,3,4,5");
request.setAttribute("forTokens2","/oracle/db/9.2.0");
JSP中的接收值
<c:forTokens items="${forTokens}" delims="," var="v"> ←分隔符为逗号
${v }<br>
</c:forTokens>
<p>
<c:forTokens items="${forTokens2}" delims="/" var="v"> ←分隔符为斜杠
${v }<br>
</c:forTokens>
结果如下:
1
2
3
4
5
oracle
db
9.2.0
⑺,c:catch,捕获异常,相当于java语法的 try......catch,可以用c:catch的var属性打印异常信息
<c:catch var="v">
<%
Integer.parseInt("heihei"); //这里故意整一个错误,把字符串转化为int格式,当然出错了
%>
</c:catch>
${v }
输出结果:
java.lang.NumberFormatException: For input string: "heihei"
⑻,c:import,相当于include,在当前页中引入另一个页面,用法如下:
<c:import url="http://localhost:8080/struts_JSTL_EL/"></c:import>
⑼,c:redirect 重定向
<c:redirect context="/struts_JSTL_EL" url="/index.jsp"></c:redirect>
结果:当前页面会重定向到 http://localhost:8080/struts_JSTL_EL/index.jsp去,就这么个事
格式化库(fmt)
在JSP中加入支持标签的语句,<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
※:先贴一段在action中的传值,后面的格式化时间和格式化数字都会用到
request.setAttribute("today",new Date());
request.setAttribute("number",1234566.678);
request.setAttribute("percent", 0.12345);
⑴,格式化时间,fmt:formatDate
<fmt:formatDate value="${today}"/><br>
输出结果:2009/04/22
<fmt:formatDate value="${today}" type="date"/><br>
输出结果:2009/04/22
<fmt:formatDate value="${today}" type="time"/><br>
输出结果:18:24:21
<fmt:formatDate value="${today}" type="both"/><br>
输出结果:2009/04/22 18:24:21
⑵,格式化数字,fmt:formatNumber
<fmt:formatNumber value="${number}"/><br>
输出结果:1,234,566.678 //type默认是数字且有逗号分隔
<fmt:formatNumber value="${number}" pattern="###,###.##"/><br>
输出结果:1,234,566.68 //pattern和struts中的一样
<fmt:formatNumber value="${number}" pattern="###,###.0000"/><br>
输出结果:1,234,566.6780 //小数点后不够4位就补零
<fmt:formatNumber value="${number}" type="currency" currencySymbol="$"/><br>
输出结果:1,234,566.68 //type设为通货,currencySymbol设美元符号
<fmt:formatNumber value="${percent}" type="percent"/><br>
输出结果:12% //type设为百分数
<fmt:formatNumber value="${percent}" type="percent" maxFractionDigits="2" minFractionDigits="2"/><br>
输出结果:12.34% //type设为百分数,且小数点后最大最小都留2位
Jsp自定义标签
Jsp页面中通过xml语法格式被调用,当JSP引擎将JSP页面翻译成Servlet时,就将这些调用转换成执行相应的Java代码
例子:实现在页面输出一个指定范围的随机数
标签:<ct:random min="1" max="100"/>
第一步:编写标签类:
实现标签类的方法有很多,最简单的方法是从javax.servlet.jsp.tagext.TagSupport类继承
java代码:
package com.test.mytag
public calss RandomTag extends TagSupport{
private int min=0;//标签中的属性min,默认值设置为0
private int max=Integer.MAX_VALUE;//标签中的属性max,默认值设置为int类型的最大值
public void setMin(int min){
this.min=min;
}
public void setMax(int max){
this.max=max
}
public int doStartTag()throws JspException{
try{
Random random=new Random();
int result=min+random.nextInt(max-min);
pageContext.getOut().write(String.valueOf(result));
//输出随机数,pageContext变量是在TagSupport类中定义的一个类变量,该变量通过TagSupport类中的
//setPageContext方法赋值,setPageContext方法是在Tag接口中定义的,
//而TagSupport实现了Tag接口的setPageContet方法,
//Servlet容器在调用doStartTag方法前会先调用setPageContext方法
}catch(IOException e){
System.out.println("error!");
}
//TagSupport类的doStartTag方法默认返回SKIP_BODY,表示忽略自定义标签体
return super.doStartTag();
}
}
第二步:
编写标签库描述符文件(TLD文件)
要想自定义标签正常工作,必须在TLD文件中对该标签进行配置:
在WEB-INF目录中建一个jsp-taglib.tld文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2.0.xsd" version="2.0">
<description>自定义标签库</descrption>
<tlib-version>1.1</tlib-version>
<short-name>ct</short-name><!--标签前缀-->
<uri>http://www.javaeye.net</uri>
<taglib>
<tag>
<desrption>产生一个指定范围的随机数</desrption>
<name>random</name>
<tag-class>com.test.mytag.RandomTag</tag-class>
<body-content>empty</body-content><!--表示标签体类型不支持标签体-->
<attribute>
<name>min</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>max</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>