分类: 系统运维
2012-03-11 10:48:40
第7章EL与JSTL标记库
7.1EL表达式语言
EL的全称是表达式语言(Expression Language,EL),它是JSP2.0新增加的技术规范。引入EL表达式语言目的之一是为JSP页面计算、访问和打印数据提供方便,尽可能减少JSP页面中的Java代码,使JSP页面更简洁、更易于开发和维护。
1).EL表达式的基本语法
EL表达式语言的基本语法为: ${表达式}
EL表达式可以写在HTML标记的标记体内,也可以写标记属性值内。
2).EL表达式中的常量和变量 EL表达中数值常量直接书写,例如${3+5}。
3).EL隐含对象
EL表达式定义了11个隐含对象来方便读取JSP环境中的数据,读取JSP作用范围变量的EL隐含对象。JSP中与作用范围有关的隐含对象是pageContext、request、session和application,EL读取这些范围内的变量时,用到的EL隐含对象有:pageScope、requestScope、sessionScope和applicationScope
4).配置
EL仅能够用于JSP 2.0(Servlet 2.4)的服务器中,比如在Tomcat 5.X可以使用,而不能在Tomcat 4.X中使用,并且必须在web.xml文件中进行配置,我们可以从web.xml文件的描述中观察出是JSP的什么版本。
xsi:schemaLocation="
/web-app_2_5.xsd" version="2.5">
在一般jsp中,注意isELIgnored字段:
在JSP中使用EL表达式jspEL.jsp
<%@ page contentType="text/html;charset=gb2312" isELIgnored="false"%>
100-50=${100-50}
8*9=${8*9}
9/3=${9/3}
${"123"+9+3}
7.1.1EL与EL隐含对象
EL表达式取变量数据的方法很简单。
1).读取JSP作用范围变量的EL隐含对象
例如:${username}的含义是取出某 个范围(四个范围的任何一个)中名称为username的变量值,因为没有指定是哪个范围中的username变量,所以会顺序从page、 request、session、application四个范围开始查找,如果找到就直接返回,不再继续查找,如果没有找到,返回null。
这样做的好处是方便,但是弊端是当pageContext中和request中都有username变量时,只能得到pageContetxt中的username变量值,如何能够得到request中的username呢?这时可以使用范围限定隐藏对象,见下面:
${pageScope.username} 只从page范围取变量username
${requestScope.username} 只从request范围取变量username
${sessionScope.username} 只从session范围取变量username
${applicationScope.username} 只从application范围取变量username
2).读取request请求报头的EL隐含对象
使用到的隐含对象是header、headerValue。headerValue的作用与request.getParameterValues()的作用相同。Header隐含对象直接读取request请求报头中指定名字的报头值。例如:
${header.host}
${header.accept}
${header.[“user-agent”]}
3).读取cookie的EL隐含对象
客户端新建一个名为aa的Cookie,然后后他通过${cookie.aa}来读取对象。
4).读取客户端表单或查询串参数的EL隐含对象
要用到EL隐含对象为param或paramValues。其中param相当于request.getParameter(),paramValues相当于调用了request.getParameterValues()。例如:${param.username}。
5). 读取上下文初始化参数的EL隐含对象
用initParam隐含对象读取上下文初始化参数。例如先在web.xml中写入:
然后在后他使用${initParam.user}读取上下文的值。
7.1.2在EL中访问JSP隐含对象的getXXX()方法
在EL表达式中访问JSP隐含对象的getXXX()方法,基本语法如下:
${pageContext.JSP隐含对象名.XXX}
例如,要访问request隐含对象中的getRequestURI()方法,在EL表达式中可写为:
${pageContext.request.requestURI}
7.1.3用EL访问JavaBean中的属性
EL表达式通过“.”算符访问JavaBean中的属性,基本用法为:
${JavaBean名.属性名}
“.”算符实际上是调用JavaBean中的getXXX()方法。
7.2JSTL.1.1
7.2.1JSTL.简介
JSTL的全称是JSP标准标记库(JSP Standard Tag Library,JSTL),它是SUN公司为简化JSP页面设计而提出的一种技术规范。
7.2.2JSTLl.1的安装
在Tomcat5.5.17中安装JSTL1.1的方法是:从下载JSTL支持库文件,将JSTL1.1的支持库文件jstl.jar和standard.jar复制到c:\tomcat\webapps\ROOT\WEB-INF\lib文件夹下,重启Tomcat即可
7.2.3JSTL标记的结构和使用
1).JSTL标记的结构
一个JSTL标记主要包含三部份:起始标记(可能包含属性)、标记体、结束标记。例如:
结果:6>5
2).在JSP页面中使用JSTL标记的方法
要在JSP页面中使用JSTL1.1标记,首先要在JSP页面中使用JSP的taglib指令加以声明,taglib指令的基本用法为:
<%@ taglib uri="标记库的URI名" prefix="标记前缀" %>
3). JSTL主要标签库
JSTL |
前置名称 |
URI |
范例 |
核心标签库 |
c |
|
|
I18N格式标签库 |
fmt |
|
|
SQL标签库 |
sql |
|
|
XML标签库 |
xml |
|
|
函数标签库 |
fn |
|
|
7.3JSTI.核心标记库
JSTL标记也叫做JSTL动作。JSTL核心标记库提供了控制流、循环语句、异常处理、信息打印、变量定义等动作。
核心标签库:
分类 |
功能分类 |
标签名称 |
Core |
表达式操作 |
out |
set | ||
remove | ||
catch | ||
流程控制 |
if | |
choose | ||
when | ||
otherwise | ||
迭代操作 |
forEach | |
forTokens | ||
URL操作 |
import | |
param | ||
url | ||
redirect |
表达式操作:out是指输出,显示数据的内容;set是设置一个值,相当于定义一个变量;remove把某个值去除;catch捕获异常,其中set、remove、catch三个标签都认为违背了MVC模式,out用的比较多。
7.3.1
1).用
用法如下:
[
2).通过
通过
[待保存的对象]
7.3.2
7.3.3
[default="变量的默认值"]
[escapeXml="true|false"]>
[变量的默认值]
7.3.4
… 可能发生异常的代码段 …
7.3.5
var="变量"
scope="变量范围">
[…标记体…..]
条件都成立时,最后显示的内容.
7.3.6
…标记体1..
…其它的
……标记体n…..
7.3.7
1).计数循环
end="终值"
[step="步长"]
[var="变量"]
[varStatus="状态变量"]>
……标记体(循环体)……..
2).集合或数组的遍历
使用
...标记体(循环体)...
7.3.8
[varStatus="状态变量"]>
[begin="初值"]
[end="终值"]
step="步长"
var="变量"
...标记体(循环体)...
7.3.9
[context=""]
[var=""]
[scope=""]
[charEncoding=""]>
...[
7.3.10
[context=""]>
...[
7.4消息国际化
JSTL中提供了一个用于实现国际化和格式化功能的标签库,我们将其简称为国际化标签库,JSP规范为国际化标签库建议的前缀名为fmt。 国际化标签库中包括了一组用于实现WEB国际化功能的标签,这组标签封装了Java语言中java.util和java.text这两个包中与国际化相关 的API类的功能。国际化标签库中提供了绑定资源包和从资源包中的本地资源文件内读取文本内容的标签,也提供了对数值和日期等本地敏感的数据按本地化信息 进行显示和解析的标签,还提供了按本地特定的时区来调整时间的标签。国际化标签库中的标签可以根据客户端浏览器的信息来自动确定本地信息,也可以由JSP页面作者显式地指定本地信息。
formatting标签库就是用于在 JSP 页面中做国际化格式化的动作,分为了两类,分别是:
国际化核心标签:
格式化标签:
7.4.1.
属性描述:
value:Locale 环境的指定,可以是 java.util.Locale 或 String 类型的实例
scope:Locale 环境变量的作用范围(可选)
如:
设置本地环境为繁体中文
设置本地环境为简体中文
7.4.2.
它只有一个属性 value ,在该属性中可以定义字符编码。
如:
7.4.3.
1).
属性描述
basename:资源配置文件的指定,只需要指定文件名而无须扩展名
prefix:前置关键字
如:
资源文件中配置的数据为:
label.backcolor=#FFF
label.fontcolor=#000
则,可以用如下方法取得label的backcolor和fontcolor值:
2).
var:
scope:变量的作用范围
如:查找一个名为 applicationMessage_zh_CN.properties 的资源配置文件,来作为显示的 Resource 绑定
7.4.4.
资源文件必须遵循如下格式:1.扩展名必须为properties,2.文件的内容必须依照key = value的格式;
属性描述
key:资源配置文件的“键”指定
bundle:若使用
var:将显示信息保存为一个变量
scope:变量的作用范围
如:
1)用
用
2)用
7.4.5.
如:在MyResourse.properties文件中,有一个索引值如下(其中,{0}代表占位符):
Str2=Hi,{0}
则,使用
也可以在资源文件中指定参数的类型:
如:在MyResourse.properties文件中,有一个索引值如下:
Str3={0,date}
则,使用
<% request.setAttribute("now",new Date()); %>
7.4.6.
属性描述:
value:时区的设置
var:
scope:变量的作用范围
7.4.7.
属性描述
value:格式化的数字,该数值可以是 String 类型或 java.lang.Number 类型的实例
type:格式化的类型,可能值包括:currency(货币)、number(数字)和percent(百分比)
pattern:格式化模式
var:结果保存变量
scope:变量的作用范围
maxIntegerDigits:指定格式化结果的最大值
minIntegerDigits:指定格式化结果的最小值
maxFractionDigits:指定格式化结果的最大值,带小数
minFractionDigits:指定格式化结果的最小值,带小数
如:
结果将被保存在“ money ”变量中,将根据 Locale 环境显示当地的货币格式
7.4.8.
属性描述
value:将被解析的字符串
type:解析格式化的类型
pattern:解析格式化模式
var:结果保存变量,类型为 java.lang.Number
scope:变量的作用范围
parseLocale:以本地化的形式来解析字符串,该属性的内容应为 String 或 java.util.Locale 类型的实例
如:
将"15%"转换为数字
7.4.9.
属性描述
value:格式化的日期,该属性的内容应该是 java.util.Date 类型的实例
type:格式化的类型
pattern:格式化模式
var:结果保存变量
scope:变量的作用范围
timeZone:指定格式化日期的时区
7.4.10.
属性描述
value:将被解析的字符串
type:解析格式化的类型
pattern:解析格式化模式
var:结果保存变量,类型为 java.lang.Date
scope:变量的作用范围
parseLocale:以本地化的形式来解析字符串,该属性的内容为 String 或 java.util.Locale 类型的实例
timeZone:指定解析格式化日期的时区
7.5SimpleTagSupport与自定义标记
7.5.1自定义标记
在JSP1.2中,提供了javax.servlet.jsp.tagext.TagSupport和BodyTagSupport等类支持用户自定义标记。在JSP2.0中,新增了javax.servlet.jsp.tagext.SimpleTagSupport类来支持用户自定义简单的标记。
如果要自定义复杂的标记处理程序,则应选择JSP1.2中的TagSupport和BodyTagSupport等作标记处理程序的父类。
7.5.2SimpleTagSupport类
SimpleTagSupport类是一个工具类,它实现了SimpleTag接口,并添加了一些方法来方便读取标记中的属性值和标记体中的内容,用户程序通过继承这个类编制出简单的标记处理程序,类中常用的方法如下:
1).默认构造方法
2).setXXX()方法
3).public void setJspBody(JspFragment jspBody)如果标记中有标记体,则调用setJspBody()方法,将标记体封装成JspFragment对象后存入实例中。
4).protected JspContext getJspContext()返回JspContext对象,上下文的。
5).public void setParent(JspTag parent)如果当前标记是嵌套在其他标记中,容器会调用此方法设置当前标记的父标记。
6).public void doTag() throws JspException, java.io.IOException业务逻辑在此方法中实现
7.5.3SimpleTagSupport的生命周期
1).SimpleTagSupport的生命周期是通过标记处理程序中各方法执行的先后顺序体现出来。
容器遇到标记时,实例化一个标记处理程序。容器调用默认构造方法实例化标记处理程序,生成一个新的实例。
2).容器调用setJspContext()方法设置上下文。如果当前标记是嵌套在其它的标记中,则调用setParent()方法。
3).如果标记中有属性,则调用setXXX()方法将标记属性值存入实例中。
4).如果标记中有标记体,则调用setJspBody()方法,将标记体封装成JspFragment对象后存入实例中。如果没有标记体,这个方法不被调用。
5).调用doTag()方法执行业务逻辑。
6).doTag()返回,结束程序。
7.5.4SimpleTagSupport的标记库描述符
标记库描述符是一个*.tld文件,它是一个XML文件。例如部署一个SimpleTagSupport标记处理程序用到的描述信息如下示
(具体参见http://blog.csdn.net/zavens/article/details/1685615):
1). 创建标记库描述符xgtimes.tld:
// 这里,该标签有三个属性body、loop、br、body是显示的文字的内容,loop设置显示的次数,br设置显示一次是否换行。
xmlns:xsi="" xsi:schemaLocation=" web-jsptaglibrary_2_0.xsd">
2). 标记处理程序xgtimes.tlds.print.java中输入内容如下:
package xgtimes.tlds;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.JspException;
public class print extends SimpleTagSupport {
private java.lang.String body;
private int loop;
private boolean br;
public void doTag() throws JspException {
JspWriter out=getJspContext().getOut();
try {
for(int i=0;i
out.print(this.body);
if(this.br) out.print("
");
}
JspFragment f=getJspBody();
if (f != null) f.invoke(out);
} catch (java.io.IOException ex) {
throw new JspException(ex.getMessage());
}
}
public void setBody(java.lang.String value) {
this.body = value;
}
public void setLoop(int value) {
this.loop = value;
}
public void setBr(boolean value) {
this.br = value;
}
}
3). 在部署描述符(web.xml)中引入标记库
在web-app标记中插入:
4). 在index.jsp中使用定制标签
首先引入标记库到页面
<%@ taglib prefix="xgtimes" uri="/xgtimes/tlds" %>
然后,插入定制标签
5).页面显示10个hello, xgtimes!
7.6TagFile与自定义标记
7.6.1标记文件
标记文件是指文件名后缀为*.tag的文本文件,它类似于*.jsp文件, JSP2.0中,用户通过继承SimpleTagSupport来自定义简单标记,另外还可以通过Tag File标记文件来定义简单标记。
例如制作一个能够显示“Hello,World!”的标记文件,并在JSP页面中调用它,在网页上显示“Hello,World!”。操作步骤如下:
1).用文本编辑器(如记事本等)建立一个文本文件,在文件中录入如下的内容:
<%
out.print("Hello,world!");
%>
将文件另存为hello.tag,存储至c:\tomcat\webapps\ROOT\WEB-INF\tags文件夹中。
2).启动Eclipse,新建一个JSP页面,改名为exam.jsp,双击打开供编辑。切换到代码视图,找到标记,在其中输入如下的代码:
<%@taglib tagdir=”/WEB-INF/tags” prefix=”demo”%>
3).预览。启动Tomcat,预览exam706.jsp,网页上显示“Hello,world!”字串。
4).查看标记文件编译生成的标记处理程序。在【我的电脑】中,打开C:\tomcat\work\Catalina\localhost\_\org\apache\jsp\tag\web文件夹,找到hello_tag.java文件,打开 查看。
7.6.2标记文件中常用的编程标记
在标记文件中常用的编程标记主要有以下几个:
1).大部分的JSP标记
2).EL表达式和JSTL1.1标记
3).<%@ tag %>指令
4).<%@ attribute %>指令
5).<%@ variable %>指令
6).
7).
7.6.3JSP页面和标记文件间传递参数的方法
JSP页面和标记文件间参数的传递是指:JSP页面如何给标记文件传入待处理的数据,标记文件如何把计算结果返回给JSP页面显示。
1).JSP页面给标记文件传入参数的方法
(1)通过JSP作用范围变量传入参数
例如,在JSP页面有以下代码:
<%
request.setAttribute("name","tomcat");
%>
<%@ taglib tagdir="/WEB-INF/tags" prefix="demo"%>
上述代码通过request作用范围变量name给标记文件传入一个值“tomcat”,则在标记文件中读取并打印的代码如下:
<%
String name=(String)request.getAttribute("name");
out.print("Hello,"+name);
%>
(2)通过标记属性传入参数
例如,在JSP页面中通过标记的name属性给标记文件传入参数值“tomcat”:
<%@ taglib tagdir="/WEB-INF/tags" prefix="demo"%>
在标记文件中读取并打印的代码如下:
<%@ attribute name="name"%>
Hello,${name}!
(3)通过标记体传入参数
待传入的参数写在标记体中,例如,在JSP页面中有以下的调用代码:
<%@ taglib tagdir="/WEB-INF/tags" prefix="demo"%>
在标记文件中读取标记体中的内容并打印的代码如下:
hello,${name}!
2).标记文件给JSP页面返回结果的方法
(1)在标记文件中直接打印输出
(2)通过导出变量返回给JSP页面
(3)通过JSP作用范围变量返回计算结果