期待已久的日子即将到来: 最新版JavaServer Pages (JSP)2.0 规范即将和其他的J2EE 1.4一同发布。新的JSP版本有一个新的飞跃,采用了新的方式:由于新的语言表达式(Expression Language,以下简称为EL)和JSP标准标签库(JSP Standard Tag Library ,以下简称为JSTL)这两种新的方式,在页面中不需要用java,对于开发一般的应用来说,重用代码变得更加容易。更具体来说,JSP 2.0带来了以下的优点:
- 首次被JSTL 1.0引入的EL现在被合并到JSP规范中,就像应用template text一样地使用所有的标准的和定制的组件。
- 新的EL已经被扩展,具备一个函数调用机制,JSTL1.1整合了一系列经常需要使用的函数。
- 新增加的变量和servlet 规范定义的错误处理机制被更好地组织起来。通过新增加的变量,JSP error pages 现在可以提供更多的错误信息。
- 容器因为更加严格的语法检查可以更容易地找出发生的错误。
- 所有的J2EE 1.4规范(包括JSP 2.0 和 Servlet 2.4),为了声明部署的规则描述而应用了XML schema。这样的好处之一是你现在可以通过任何顺序列出web.xml文件中的描述。JSP 2.0也增加了一些新的配置选项用于部署描述,允许通过全局的配置来代替基于每页的配置。
- 由于更具伸缩性的规则和新的自定义action element,现在就像编写XML文件一样,编写JSP页面变得更加容易。
- 定制的标签库现在可以开发成一系列的标签文件(具有JSP元素的文本文件),标签处理器可以使用新的、简化的标签处理器的API。与此同时,新规范加入了一些新的特性,比如:支持在jsp页面上显示动态属性列表和可执行片断属性。 在众多的书籍中,这是头一个讲解JSP 2.0新特性的文章。在这一部分,我们将看到和EL相关的信息,其他的新特性留到后面。在这里我假定读者已经熟悉JSP 1.2,而且至少听说过JSTL。 你可能对这本第三版的《JavaServer Pages》感兴趣。这本书中,我尽可能在细节上讲述所有的内容,而且并不认为你对JSP或者JSTL了解一切。这本书预计在2003年12月 出版,但是你现在可以在http://www.amazon.com、Barnes&Noble,或者其他在线书店预订。 EL(The Expression Language) 如果过去使用过JSTL,那么你可能已经熟悉 了EL。EL在JSTL 1.0规范中被引入,用来在运行期间对Java表达式中action element属性赋值提供另一种选择。当JSTL EL已经非常迅速的流行起来情况下,还是存在一个问题: JSTL EL 表达式仅仅可以与JSTL和custom action一起使用,怎样才能使用非标准API对EL表达式求值? JSP 2.0中,JSP容器自己可以理解EL表达式。这使你在所有过去只能应用Java表达式的地方应用EL表达式成为可能,比如:标准和定制action的属性值,模板文本。 在我们看具体的例子前,让我们更进一步的看看 什么是EL。EL是从JavaScript中获得启发的一种语言,XPath(一种用来访问XML文档的语言),但是EL在对变量的null值和执行更多 数据类型的自动类型转换的处理上更加宽松。这些新特性对于web应用非常重要,在这些应用中输入通常通过html表单的request parameter来得到。这些参数可能仅仅在某些请求下才能体现出来,而且浏览器经常将request parameter作为文本发送,然而应用程序经常需要把他们作为数字类型、布尔类型(true 或者 false)来使用。通过EL,你根本就很少需要关心缺少某些参数的值或者类型转换。 一个EL表达式包含变量和操作符。任何存储在某个JSP作用范围(如:page、 request、session、application)的bean能被作为一个EL变量来使用。另外,EL支持以下预定义的变量:
变量名称 | 说明 |
pageScope | 一个包含所有page scope范围的变量集合 (a java.util.Map) |
requestScope | 一个包含所有request scope范围的变量集合 (a java.util.Map) |
sessionScope | 一个包含所有session scope范围的变量集合 (a java.util.Map) |
applicationScope | 一个包含所有application scope范围的变量集合 (a java.util.Map) |
param | 一个包含所有请求参数的集合 (a java.util.Map),通过每个参数对应一个String值的方式赋值 |
paramValues | 一个包含所有请求参数的集合 (a java.util.Map),通过每个参数对应一个String数组的方式赋值 |
header | 一个包含所有请求的头信息的集合, (a java.util.Map) ,通过每个头信息对应一个String值的方式赋值 |
headerValues | 一个包含所有请求的头信息的集合 (a java.util.Map) ,通过每个头信息的值都保存在一个String数组的方式赋值 |
cookie | 一个包含所有请求的 cookie集合 (a java.util.Map), 通过每一个cookie(javax.servlet.http.Cookie)对应一个cookie值的方式赋值 |
initParam | 一个包含所有应用程序初始化参数的集合(a java.util.Map) ,通过每个参数分别对应一个String值的方式赋值 |
pageContext | 一个javax.servlet.jsp.PageContext类的实例, 用来提供访问不同的请求数据 |
Operator | Description |
. | 访问一个bean属性或者 Map entry |
[] | 访问一个数组或者链表元素 |
() | 对子表达式分组,用来改变赋值顺序 |
? : | 条件语句,比如: 条件 ? ifTrue : ifFalse.如果条件为真,表达式值为前者,反之为后者 |
+ | 数学运算符,加操作 |
– | 数学运算符,减操作或者对一个值取反 |
* | 数学运算符,乘操作 |
/ or div | 数学运算符,除操作 |
% or mod | 数学运算符,模操作(取余) |
== or eq | 逻辑运算符,判断符号左右两端是否相等,如果相等返回true,否则返回false |
!= or ne | 逻辑运算符,判断符号左右两端是否不相等,如果不相等返回true,否则返回false |
< or lt | 逻辑运算符,判断符号左边是否小于右边,如果小于返回true,否则返回false |
> or gt | 逻辑运算符,判断符号左边是否大于右边,如果大于返回true,否则返回false |
<= or le | 逻辑运算符,判断符号左边是否小于或者等于右边,如果小于或者等于返回true,否则返回false |
>= or ge | 逻辑运算符,判断符号左边是否大于或者等于右边,如果大于或者等于返回true,否则返回false |
&& or and | 逻辑运算符,与操作赋。如果左右两边同为true返回true,否则返回false |
|| or or | 逻辑运算符,或操作赋。如果左右两边有任何一边为true返回true,否则返回false |
! or not | 逻辑运算符,非操作赋。如果对true取运算返回false,否则返回true |
empty | 用来对一个空变量值进行判断: null、一个空String、空数组、 空Map、没有条目的Collection集合 |
func(args) | 调用方法, func是方法名,args是参数,可以没有,或者有一个、多个参数.参数间用逗号隔开 |
库 | URI | 前缀 |
Core | http://java.sun.com/jsp/jstl/core | c |
XML processing | http://java.sun.com/jsp/jstl/xml | x |
I18N formatting | http://java.sun.com/jsp/jstl/fmt | fmt |
Database access | http://java.sun.com/jsp/jstl/sql | sql |
Functions | http://java.sun.com/jsp/jstl/functions | fn |
public static int length(Object obj)
throws JspTagException {
if (obj == null)
return 0;
if (obj instanceof String)
return ((String)obj).length();
if (obj instanceof Collection)
return ((Collection)obj).size();
if (obj instanceof Map)
return ((Map)obj).size();
int count = 0;
if (obj instanceof Iterator) {
Iterator iter = (Iterator) obj;
count = 0;
while (iter.hasNext()) {
count++;
iter.next();
}
return count;
}
if (obj instanceof Enumeration) {
Enumeration enum = (Enumeration) obj;
count = 0;
while (enum.hasMoreElements()) {
count++;
enum.nextElement();
}
return count;
}
try {
count = Array.getLength(obj);
return count;
} catch (IllegalArgumentException ex) {}
throw new JspTagException("Unsupported type"));
}
就像你所看到的,在那里没有什么出奇的地方。它是一个常规的静态方法,这个函数中通过对运行期中的参数类别的判断,找出参数的长度。
除了在这个方法中使用的length()方法,JSTL1.1标签库还包含了许多其它经常使用的函数:函数 | 描述 |
fn:contains(string, substring) | 如果参数string中包含参数substring,返回true |
fn:containsIgnoreCase(string, substring) | 如果参数string中包含参数substring(忽略大小写),返回true |
fn:endsWith(string, suffix) | 如果参数 string 以参数suffix结尾,返回true |
fn:escapeXml(string) | 将有特殊意义的XML (和HTML)转换为对应的XML character entity code,并返回 |
fn:indexOf(string, substring) | 返回参数substring在参数string中第一次出现的位置 |
fn:join(array, separator) | 将一个给定的数组array用给定的间隔符separator串在一起,组成一个新的字符串并返回。 |
fn:length(item) | 返回参数item中包含元素的数量。参数Item类型是数组、collection或者String。如果是String类型,返回值是String中的字符数。 |
fn:replace(string, before, after) | 返回一个String对象。用参数after字符串替换参数string中所有出现参数before字符串的地方,并返回替换后的结果 |
fn:split(string, separator) | 返回一个数组,以参数separator 为分割符分割参数string,分割后的每一部分就是数组的一个元素 |
fn:startsWith(string, prefix) | 如果参数string以参数prefix开头,返回true |
fn:substring(string, begin, end) | 返回参数string部分字符串, 从参数begin开始到参数end位置,包括end位置的字符 |
fn:substringAfter(string, substring) | 返回参数substring在参数string中后面的那一部分字符串 |
fn:substringBefore(string, substring) | 返回参数substring在参数string中前面的那一部分字符串 |
fn:toLowerCase(string) | 将参数string所有的字符变为小写,并将其返回 |
fn:toUpperCase(string) | 将参数string所有的字符变为大写,并将其返回 |
fn:trim(string) | 去除参数string 首尾的空格,并将其返回 |