本章中所有的例子程序都在名为JSTL的WEB应用程序中运行,使用的Tomcat服务器版本为Tomcat5.5。为了简化代码和突出重点,本章中所有的JSP网页文件的例子程序都省略了、
、如果属性的值用斜体字表示,表示该属性可以是表达式;如果标签体的内容用斜体字表示,表示标签体的内容可以是JSP代码。
为了本章后面讲解的方便,这里先创建一个名为UserBean的JavaBean程序,如例程8-1所示。
例程 8-1 UserBean.java
package org.it315;
public class UserBean
{
private String userName;
private String password;
private String address;
private int visitCount;
public void setUserName(String userName)
{
this.userName = userName;
}
public String getUserName()
{
return userName;
}
public void setPassword(String password)
{
this.password = password;
}
public String getPassword()
{
return password;
}
public void setAddress(String address)
{
this.address = address;
}
public String getAddress()
{
return address;
}
public void setVisitCount(int visitCount)
{
this.visitCount = visitCount;
}
public int getVisitCount()
{
return visitCount;
}
}
编译这个源程序,将编译后的UserBean.class文件放在
从JSP 1.1规范开始JSP就支持使用自定义标签,使用自定义标签大大降低了JSP页面的复杂度,同时增强了代码的重用性,因此自定义标签在WEB应用中被广泛使用。许多WEB应用厂商都开发出了自己的一套标签库提供给用户使用,这导致出现了许多功能相同的标签,令网页制作者无所适从,不知道选择哪一家的好。为了解决这个问题,Apache Jakarta小组归纳汇总了那些网页设计人员经常遇到的问题,开发了一套用于解决这些常用问题的自定义标签库,这套标签库被SUN公司定义为标准标签库(The JavaServer Pages Standard Tag Library),简称JSTL。使用JSTL可以解决用户选用不同WEB厂商的自定义标签时的困惑,JSP规范同时也允许WEB容器厂商按JSTL标签库的标准提供自己的实现,以获取最佳性能。
由于JSTL是在JSP 1.2规范中定义的,所以JSTL需要运行在支持JSP 1.2及其更高版本的WEB容器上,例如,Tomcat 5.5。
1.JSTL的逻辑组成
笔者在写本章内容时的JSTL规范的最新版本是JSTL 1.1,它是JSP 2.0最新规范中的一个重要组成部分。JSTL 1.1中包含四个标签库和一组EL函数。为方便用户使用,JSP规范中描述了JSTL的各个标签库的URI地址和建议使用的前缀名,如表8.1所示。本章中在使用JSTL标签时,使用的都是这些建议的前缀。
表8.1 JSTL
标签库功能描述 |
标签库的URI |
建议前缀 |
核心标签库 |
http://java.sun.com/jsp/jstl/core |
c |
XML标签库 |
http://java.sun.com/jsp/jstl/xml |
x |
国际化/格式化标签库 |
http://java.sun.com/jsp/jstl/fmt |
fmt |
数据库标签库 |
http://java.sun.com/jsp/jstl/sql |
sql |
EL自定义函数 |
http://java.sun.com/jsp/jstl/functions |
fn |
下面对JSTL的各个标签库进行简单的介绍:
(1)核心标签库中包含了实现WEB应用中的通用操作的标签。例如,用于输出一个变量内容的
(2)国际化/格式化标签库中包含实现WEB应用程序的国际化的标签。例如,设置JSP页面的本地信息、设置JSP页面的时区、绑定资源文件,使本地敏感的数据(例如数值、日期等)按照JSP页面中设置的本地格式显示。
(3)数据库标签库中包含用于访问数据库和对数据库中的数据进行操作的标签。例如,从数据源中获得数据库连接、从数据库表中检索数据等。由于在软件分层的开发模型中,JSP页面仅用作表现层,我们一般不在JSP页面中直接操作数据库,而是在业务逻辑层或数据访问层操作数据库,所以,JSTL中提供的这套数据库标签库没有多大的实用价值。
(4)XML标签库中包含对XML文档中的数据进行操作的标签。例如,解析XML文档、输出XML文档中的内容,以及迭代处理XML文档中的元素。因为XML广泛应用于WEB开发,对XML文档的处理非常重要,XML标签库使处理XML文档变得简单方便,这也是JSTL的一个重要特征。
(5)JSTL中提供的一套EL自定义函数包含了JSP页面制作者经常要用到的字符串操作。例如,提取字符串中的子字符串、获取字符串的长度和处理字符串中的空格等。
2.JSTL的物理组成
完整的JSTL应包含SUN公司提供的jstl.jar 包和WEB容器产商提供的JSTL实现包,以Apache Jakarta 小组提供的JSTL实现包为例,完整的JSTL包含jstl.jar、standard.jar 和 xalan.jar 三个 jar 包。sun 公司提供的jstl.jar 包封装了 JSTL所要求的一些API 接口和类,Apache Jakarta 小组编写的 JSTL API 实现类封装在standard.jar包中。由于 JDK 在 JDK 1.5 版本中才引入了 XPath API,而 apache Jakarta 小组开发的 JSTL API 是在 JDK1.5 之前推出的,所以 apache Jakarta 小组在 JSTL 中使用的是他们自己开发的 XPath API,这些 API 封装在 xalan.jar 包中。Standard.jar 包中包括核心标签库、国际化/格式化标签库、数据库标签库中的标签和标准的EL自定义函数的实现类,xalan.jar 包中包括 JSTL 解析 XPath 的相关 API 类。
1.下载JSTL包
可以从Apache的网站下载JSTL的jar包。进入http://jakarta.apache.org/taglibs/ 页面,根据相关的提示信息下载 zip压缩文件,这个压缩文件中包含JSTL的三个jar包。
提示:由于网站的不断升级,下载JSTL 的jar包的网址可能改变。读者在下载这些文件时,如果在指定的网址没有下载的链接,可以进入Apache的网站首页,然后根据相关的提示下载所需的文件。例如,笔者在编写JSTL初稿时,从http://jakarta.apache.org/taglibs/ 下载的压缩文件中只包含jstl.jar和standard.jar两个 jar 包,而 xalan.jar包要从 http://xml.apache.org/xalan-j/downloads.html 下载。
2.安装JSTL
在Tomcat中安装JSTL很简单,只要将 JSTL的jar包复制到
提示:Tomcat 5.5自带的JSP例子应用程序中提供了使用JSTL标签的例子,在
3.测试JSTL
安装完JSTL后,接下来就可以准备测试JSTL安装得是否成功了。
Apache小组在提供JSTL时,同时也提供了JSTL标签的标签描述文件(即TLD文件),它们都封装在standard.jar包中,位于该jar文件的META-INF目录中。用WinRAR 打开standard.jar包,进入META-INF目录,可以看到JSTL标签的标签库描述文件。查看这些TLD源文件,可以看到文件中定义的
要在JSP文件中使用JSTL,首先就需要使用taglib指令导入所需要使用的JSTL标签库,taglib指令的uri属性必须为相应标签库的TLD文件中的
例程8-2 test.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
上面的test.jsp页面中的
启动Tomcat后,在浏览器地址栏中输入test.jsp页面的地址进行访问,如果浏览器中显示出了“hello world!”,说明JSTL安装成功。
JSTL核心标签库包含了一组用于实现WEB应用中的通用操作的标签,JSP规范为核心标签库建议的前缀名为c。
表8.2 特殊字符转换
语法1,没有标签体的情况:
[escapeXml="{true|false}"]
[default="defaultValue"] />
语法2,有标签体的情况,在标签体中指定输出的默认值:
[escapeXml="{true|false}"] >
default value
表8.3
属性名 |
是否支持EL |
属性类型 |
属 性 描 述 |
value |
true |
Object |
指定要输出的内容 |
escapeXml |
true |
Boolean |
指定是否将>、<、&、'、" 等特殊字符进行HTML编码转换后再进行输出。默认值为true |
default |
true |
Object |
指定如果value属性的值为null时所输出的默认值 |
当且仅当value属性的值为null时,
例程8-3是
例程8-3 c_out1.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%
session.setAttribute("test_session", "testValue_session");
%>
直接输出一个字符串:
输出Web域中不存在的属性的值:
输出Web域中的test_session属性的值:
例程8-3的运行结果如图8.1所示。
图8.1
例程8-4和例程8-5是两个用于演示
例程8-4 c_out2.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
例程8-5 c_out3.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
例程8-4和例程8-5的运行结果分别如图8.2和图8.3所示。
图8.2
图8.3
语法1,使用value属性设置指定域中的某个属性的值:
var="varName"
[scope="{page|request|session|application}"] />
语法2,在标签体中设置指定域中的某个属性的值:
[scope="{page|request|session|application}"]>
body content
语法3,使用value属性设置Web域中的一个属性对象的某个属性:
target="target"
property="propertyName" />
语法4,在标签体中设置Web域中的一个属性对象的某个属性性:
property="propertyName">
body content
表8.4
属性名 |
是否支持EL |
属性类型 |
属 性 描 述 |
value |
true |
Object |
用于指定属性值 |
var |
false |
String |
用于指定要设置的Web域属性的名称 |
scope |
false |
String |
用于指定属性所在的Web域 |
target |
true |
Object |
用于指定要设置属性的对象,这个对象必须是JavaBean对象或java.util.Map对象 |
property |
true |
string |
用于指定当前要为对象设置的属性名称 |
如果使用第1种语法格式时的value属性值为null,或者使用第2种语法格式时的标签体内容为空,
在第3种语法格式和第4语法格式中,如果target属性的值是java.util.Map对象,property属性表示该Map对象的关键字,如果Map对象没有指定的关键字,就给Map对象增加指定的关键字;如果target属性的值是JavaBean对象,property属性表示JavaBean对象的属性,如果value的类型与JavaBean属性的类型不匹配时,会根据EL的转换规则自动进行转换。当使用第3种语法格式或第4种语法格式时,如果target属性的值为null(即target属性指定的对象不存在),或者target属性的值是一个JavaBean对象,但该JavaBean中不存在property属性指定的属性,
例程8-6是使用
例程8-6 c_set1.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
zxx
输出session 作用域中的userNamer属性的值:
输出session 作用域中的bookname属性的值:
例程8-6的运行结果如图8.4所示。
图8.4
例程8-7是使用
例程8-7 c_set2.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.HashMap" %>
<%
HashMap preferences = new HashMap();
session.setAttribute("preferences",preferences);
%>
设置和输出UserBean对象的userName属性值:
设置和输出UserBean对象的password属性值:
设置和输出Map对象的color关键字的值:
在浏览器地址栏输入如下地址访问例程8-7:
http://localhost:8080/JSTL/c_set2.jsp?color=green
例程8-7的运行结果如图8.5所示。
图8.5
[scope="{page|request|session|application}"] />
var属性用于指定要删除的属性的名称,scope属性用于指定要删除的属性所属的Web域,它们的值都不能接受动态值。如果没有指定scope属性,
例程8-8是使用
例程8-8 c_remove.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
a123456a
在没有使用 <c:remove> 标签之前,变量的值为:
company:
passWord:
在使用 <c:remove> 标签之后,变量的值为:
company:
passWord:
例程8-8的运行结果如图8.6所示。
图8.6
nested actions
var属性用于标识
例程8-9是使用
例程8-9 c_catch.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%
int i = 0;
int j = 10;
out.println(j + "/" + i + "=" + j/i);
%>
异常:
异常 myex.getMessage:
异常 myex.getCause:
异常 myex.getStackTrace:
在例程8-9中,
图8.7
JSP页面的显示逻辑中也经常需要进行条件判断,
语法1,没有标签体的情况:
[scope="{page|request|session|application}"] /> 语法2,有标签体的情况,在标签体中指定要执行的内容: [scope="{page|request|session|application}"]> body content
表8.5
属性名 |
是否支持EL |
属性类型 |
属 性 描 述 |
test |
true |
boolean |
决定是否处理标签体中的内容的条件表达式 |
var |
false |
String |
用于指定将test属性的执行结果保存到某个Web域中的某个属性的名称 |
scope |
false |
String |
指定将test属性的执行结果保存到哪个Web域中 |
对于语法2,如果指定了
例程8-10是使用
例程8-10 c_if.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
这是您第一次访问本网站,欢迎您!
在浏览器地址栏输入如下地址访问例程8-10:
http://localhost:8080/JSTL/c_if.jsp?count=1
例程8-10的运行结果如图8.8所示。
图8.8
当JSP页面中使用
例程8-11是使用
例程8-11 c_choose.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
对不起,没有符合您要求的记录。
符合您要求的记录共有${count}条.
在浏览器地址栏输入如下地址访问例程8-11:
http://localhost:8080/JSTL/c_choose.jsp?count=0
例程8-11的运行结果如图8.9所示。如果将参数count的值修改为10,则运行结果如图8.10所示。
图8.9
图8.10
例程8-12是一个综合使用
例程8-12 c_customLogic.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Your favourite course is computer.
Your favourite course is other.
在浏览器地址栏中直接访问c_customLogic.jsp的运行结果如图8.11所示,在文本框中输入“computer”,单击其中的submit按钮后的运行结果如图8.12所示。
图8.11
图8.12
JSP页面的显示逻辑中也经常需要对集合对象进行循环迭代操作,
语法1,在集合对象中迭代:
items="collection"
[varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
语法2,迭代固定的次数:
[varStatus="varStatusName"]
begin="begin" end="end" [step="step"]>
body content
表8.6
属性名 |
是否支持EL |
属性类型 |
属 性 描 述 |
var |
false |
String |
指定将当前迭代到的元素保存到page这个Web域中的属性名称 |
items |
true |
任何支持的类型 |
将要迭代的集合对象 |
varStatus |
false |
String |
指定将代表当前迭代状态信息的对象保存到page这个Web域中的属性名称 |
begin |
true |
int |
如果指定items属性,就从集合中的第begin个元素开始进行迭代,begin的索引值从0开始编号;如果没有指定items属性,就从begin指定的值开始迭代,直到end值时结束迭代 |
end |
true |
int |
参看begin属性的描述 |
step |
true |
int |
指定迭代的步长,即迭代因子的迭代增量 |
在使用
items属性还支持与数据库有关的数据类型java.sql.ResultSet(包括javax.sql.RowSet),这些数据类型将在8.5 节的数据库标签中进行介绍。对字符串的迭代操作通常使用
1.迭代Collection类型的集合对象
例程8-13是使用
例程8-13 c_forEach_collection.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.*,org.it315.UserBean" %>
<%
Collection users = new ArrayList();
for(int i=0; i<5; i++)
{
UserBean user = new UserBean();
user.setUserName("user" + i);
user.setPassword("guess" + i);
users.add(user);
}
session.setAttribute("users", users);
%>
用户名 密码
${user.userName} ${user.password}
例程8-13的运行结果如图8.13所示。
图8.13
2.迭代Map对象
使用
EL中的requestScope隐含对象代表request作用域中的所有属性的Map对象,所以我们可以使用
例程8-14 c_forEach_map.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%
request.setAttribute("attr1","value1");
request.setAttribute("attr2","value2");
%>
Map的关键字 Map的对应关键字的值 ${entry.key} ${entry.value}
例程8-14的运行结果如图8.14所示。
图8.14
3.迭代指定的次数
例程8-15 c_forEach_count.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
从11到16迭代,指定迭代步长为2:
${i}
从0到5迭代,没有指定迭代步长:
${i}
例程8-15的运行结果如图8.15所示。
图8.15
4.指定迭代集合对象的范围和步长
例程8-16 c_forEach_col.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.*,org.it315.UserBean" %>
<%
Collection users = new ArrayList();
for(int i=0; i<6; i++)
{
UserBean user = new UserBean();
user.setUserName("user" + i);
user.setPassword("guest" + i);
users.add(user);
}
session.setAttribute("users", users);
%>
用户名 密码
${user.userName} ${user.password}
例程8-16的运行结果如图8.16所示。
图8.16
5.获取迭代的状态信息
不管是迭代集合对象,还是迭代指定的次数,在迭代时都可以获得当前的迭代状态信息。
例程8-17是一个获取迭代状态信息的例子程序。
例程8-17 c_forEach_col2.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.*,org.it315.UserBean" %>
<%
Collection users = new ArrayList();
for(int i=0; i<6; i++)
{
UserBean user = new UserBean();
user.setUserName("user" + i);
user.setPassword("guest" + i);
users.add(user);
}
session.setAttribute("users", users);
%>
用户名 密码 index
count first? last?
${user.userName} ${user.password} ${sta.index} ${sta.count} ${sta.first} ${sta.last}
数值 index count
first? last?
${i} ${sta1.index} ${sta1.count} ${sta1.first} ${sta1.last}
例程8-17的运行结果如图8-17所示。
图8.17
6.与条件标签结合使用
迭代标签可以与条件标签结合使用,对数据进行有条件的迭代,应用举例如例程8-18所示。
例程8-18 c_forEach_com.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
偶数行 奇数行
例程8-18的运行结果如图8.18所示。
图8.18 [var="varName"] [varStatus="varStatusName"] [begin="begin"] [end="end"] [step="step"]> body content
表8.7 c:forTokens 属性名 是否支持EL 属性类型 属 性 描 述 var false String 指定将当前迭代出的子字符串保存到page这个Web域中的属性名称 items true String 将要迭代的字符串 delims true String 指定一个或多个分隔符 varStatus false String 指定将代表当前迭代状态信息的对象保存到page这个Web域中的属性名称,代表当前迭代的状态信息的对象的类型为javax.servlet.jsp.jstl.core.LoopTagStatus,从JSTL规范中可以查看这个类的详细信息 begin true int 指定从第begin个子字符串开始进行迭代,begin的索引值从0开始编号 end true int 指定迭代到第begin个子字符串,begin的索引值从0开始编号 step true int 指定迭代的步长,即每次迭代后的迭代因子增量 在使用 例程8-19是一个使用 例程8-19 c_forTokens.jsp <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=gb2312" %> 使用"|"作为分隔符 ${token}© 使用"|"和","作为分隔符 ${token}© 使用"-"作为分隔符 ${token}©
例程8-19的运行结果如图8.19 所示。
图8.19 JSTL核心标签库中提供了如下一些与URL操作相关的标签: 在举例讲解上面的某些标签时,要引用另外一个JSP文件,这里先创建好这个JSP文件,如例程8-20所示。 例程8-20 register.jsp <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> <%@ page contentType="text/html;charset=gb2312" %> <% String name = request.getParameter("name"); name = new String(name.getBytes("iso-8859-1"),"gb2312"); session.setAttribute("name",name); String country = request.getParameter("country"); country = new String(country.getBytes("iso-8859-1"),"gb2312"); session.setAttribute("country",country); %> name=${name}; country=${country} 在JSP页面进行URL的相关操作时,经常要在URL地址后面附加一些参数。 语法1,使用value属性指定参数的值: 语法2,在标签体中指定参数的值: parameter value 表8.8 语法1,没有标签体的情况: [context="context"] [var="varName"] [scope="{page|request|session|application}"] /> 语法2,有标签体的情况,在标签体中指定构造的URL的参数: [context="context"] [var="varName"] [scope="{page|request|session|application}"]>
表8.9 属性名 是否支持EL 属性类型 属 性 描 述 value true String 指定要构造的URL context true String 当要使用相对路径导入同一个服务器下的其他WEB应用程序中的URL地址时,context属性指定其他WEB应用程序的名称 var false String 指定将构造出的URL结果保存到Web域中的属性名称 scope false String 指定将构造出的URL结果保存到哪个Web域中 value属性所指定的URL可以是相对路径和绝对路径,其具体细节与8.3.12节的 例程8-21是一个使用 例程8-21 c_url.jsp <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=gb2312" %> 使用绝对路径构造URL:
使用相对当前JSP页面的路径构造URL: 使用相对当前WEB应用的路径构造URL: 在浏览器地址栏输入如下地址访问例程8-21: http://localhost:8080/JSTL/c_url.jsp?country=China 查看例程8-21的运行结果的源文件,内容如例程8-22所示。 例程8-22 c_url.jsp运行结果的源文件 使用绝对路径构造URL: 使用相对当前JSP页面的路径构造URL: 使用相对当前WEB应用的路径构造URL: 语法1,将URL地址指向的资源内容以字符串形式输出或以字符串形式保存到一个变量中: [context="context"] [var="varName"] [scope="{page|request|session|application}"] [charEncoding="charEncoding"]> optional body content for
语法2,将URL地址指向的资源内容保存到一个Reader对象中: [context="context"] varReader="varReaderName" [charEncoding="charEncoding"]> body content where varReader is consumed by another action
表8.10 属性名 是否支持EL 属性类型 属 性 描 述 url true String 指定要导入的资源的URL地址 context true String 当要使用相对路径导入同一个服务器下的其他WEB应用程序中的资源时,context属性指定其他WEB应用程序的名称 var false String 指定将导入的资源内容保存到Web域中的属性名称 scope false String 指定将导入的资源内容保存到哪个Web域中 charEncoding true String 将导入的资源内容转换成字符串时所使用的字符集编码 varReader false String 指定将导入的资源内容保存到page域中的一个java.io.Reader对象中,varReader属性指定了该Reader对象在page这个Web域中的属性名称。 使用 当使用第1种语法格式时,如果指定了var属性,导入的资源内容以字符串形式保存到一个变量中,var属性指定了这个变量保存在Scope属性指定的Web域中的名称;如果没有指定var属性,导入的资源内容将以字符串形式直接输出。第1种语法格式的标签体内中可以嵌套 使用第2种语法格式时,导入的资源内容保存到page域中的一个java.io.Reader对象中,varReader属性指定了该Reader对象在page这个Web域中的属性名称。因为 使用 1.使用相对URL导入其他资源文件 (1)当被导入的外部资源文件与当前JSP文件属于同一个WEB应用程序时,JSP容器对资源路径的处理与 (2)当被导入的外部资源文件与JSP文件属于同一个服务器下的不同的WEB应用时,如果要使用相对路径,路径必须以“/”开始。此时, 2.使用绝对URL导入其他资源 使用绝对路径导入外部资源文件时,即使被导入的文件与当前JSP文件属于同一个WEB应用程序,被导入的资源文件也不会共享当前JSP页面的request和session对象。因为在这种情况下,当前JSP文件所属的Web服务器充当了一个Http客户端程序,去访问绝对路径所指定的外部资源文件,然后将响应结果的实体内容加入到当前JSP页面中,此时,访问当前JSP页面的客户端是浏览器,而访问绝对路径所指定的外部资源文件的客户端是当前JSP文件所属的Web服务器,这显然属于两个不同的客户端,所以,被导入的资源文件和当前JSP页面不可能共享request和session对象。 例程8-23是使用 例程8-23 c_import.jsp <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=gb2312" %> 使用相对路径导入同一个WEB应用中的资源: 使用相对路径导入同一个服务器下的不同WEB应用中的资源: 使用绝对路径导入资源示例1: 使用绝对路径导入资源示例2: charEncoding="gb2312">
${myImport} 在浏览器地址栏输入如下地址访问例程8-23,其运行结果如图8.20 所示: http://localhost:8080/JSTL/c_import.jsp?name=zxx&country=China
图8.20 在 语法1,没有标签体的情况: 语法2,有标签体的情况,在标签体中指定重定向时的参数:
表8.11 属性名 是否支持EL 属性类型 属 性 描 述 url true String 指定要转发或重定向到的目标资源的URL地址 context true String 当要使用相对路径重定向到同一个服务器下的其他WEB应用程序中的资源时,context属性指定其他WEB应用程序的名称 url属性指定将要重定向的资源的URL时,可以使用相对路径和绝对路径,其具体细节与 例程8-24 c_redirect.jsp <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=gb2312" %>
例程8-24的运行结果如图8.21 所示。
图8.21 为了简化WEB应用的国际化开发,JSTL中提供了一个用于实现国际化和格式化功能的标签库,我们将其简称为国际化标签库,JSP规范为国际化标签库建议的前缀名为fmt。国际化标签库中包括了一组用于实现WEB国际化功能的标签,这组标签封装了Java语言中java.util和java.text这两个包中与国际化相关的API类的功能。国际化标签库中提供了绑定资源包和从资源包中的本地资源文件内读取文本内容的标签,也提供了对数值和日期等本地敏感的数据按本地化信息进行显示和解析的标签,还提供了按本地特定的时区来调整时间的标签。 国际化标签库中的标签可以根据客户端浏览器的信息来自动确定本地信息,也可以由JSP页面作者显式地指定本地信息。如果没有特别指定,本章案例假设默认的本地信息为“中文(中国)”。 在举例讲解国际化标签库中的标签时, 通常要使用到包含有多个资源文件的资源包,这个资源包中的各个资源文件分别对应几个不同本地信息。这里先创建好一组资源包文件。首先按例程8-25和例程8-26创建两个名称分别为greetings.properties和temp.properties的资源文件。 例程8-25 greetings.properties org.it315.heading=The first WEB application org.it315.welcome=Welcome to www.it315.org ! org.it315.okKey=Today is {0,date,full}, you have {1,number,currency} dollars. 例程8-26 temp.properties org.it315.heading=第一个WEB应用程序 org.it315.welcome=欢迎访问www.it315.org网站! org.it315.okKey=今天是{0,date,full},你有{1,number,currency}元。 接着使用JDK中提供的native2ascii程序将temp.properties文件中的中文字符转换成其Unicode码形式的转义序列。在命令行窗口中进入temp.properties文件所在的目录,执行如下命令: native2ascii -encoding GB2312 temp.properties greetings_zh.properties 上面的命令执行后产生的greetings_zh.properties文件内容如例程8-27所示。 例程8-27 greetings_zh.properties org.it315.heading=\u7b2c\u4e00\u4e2aWEB\u5e94\u7528\u7a0b\u5e8f org.it315.welcome=\u6b22\u8fce\u8bbf\u95eewww.it315.org\u7f51\u7ad9! org.it315.okKey=\u4eca\u5929\u662f{0,date,full}\uff0c\u4f60\u6709{1,number, currency}\u5143\u3002 英文本地环境所对应的资源文件只需复制greetings.properties文件,并改名为greetings_en.properties即可。最后将greetings.properties、greetings_en.properties和greetings_zh.properties这三个资源文件保存到 [variant="variant"] [scope="{page|request|session|application}"] /> 表8.12 属性名 是否支持EL 属性类型 属 性 描 述 value true String或java.util.Locale 指定用户的本地化信息,可以是一个字符串或java.util.Locale实例对象。如果是字符串,则必须包含小写形式的语言编码,其后也可以带有大写形式的国家编码,两者中间用“-”或“_”连接 variant true String 指定创建Locale实例对象时设置的变量部分,它用于标识开发商或特定浏览器为实现扩展功能而自定义的信息 scope false String 指定将构造出的Locale实例对象保存在哪个Web作用域中 如果 例程8-28 fmt_setLocale.jsp <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=gb2312" %>
<% session.setAttribute("number", new Integer(8888888)); %>
例程8-28中的 在浏览器地址栏输入如下地址访问fmt_setLocale.jsp页面: http://localhost:8080/JSTL/fmt_setLocale.jsp?locale=en_US 例程8-28的运行结果如图8.22所示。
图8.22 将上面的访问地址中的locale参数设置为zh_CN后访问fmt_setLocale.jsp页面,例程8-28的运行结果如图8.23所示。
图8.23 [var="varName"] [scope="{page|request|session|application}"] /> 表8.13 属性名 是否支持EL 属性类型 属 性 描 述 basename true String 指定创建ResourceBundle实例对象的基名 var false String 指定将创建出的ResourceBundle实例对象保存到Web域中的属性名称 scope false String 指定将创建出的ResourceBundle实例对象保存在哪个Web作用域中 (1)如果basename属性的值为null或空字符串,或找不到basename属性指定的资源, (2)如果指定了var属性, (3)如果没有指定var属性, 在前面的例程8-28中已经使用了 [prefix="prefix"]> body content
表8.14 属性名 是否支持EL 属性类型 属 性 描 述 basename true String 指定创建ResourceBundle实例对象的基名 prefix true String 指定追加到嵌套在 如果设置了 例程8-29是一个使用 例程8-29 fmt_bundle.jsp <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=gb2312" %> 没有设置prefix属性的情况:
设置prefix属性的情况:
例程8-29的运行结果如图8.24所示。
图8.24 语法1,没有标签体的情况: [bundle="resourceBundle"] [var="varName"] [scope="{page|request|session|application}"] /> 语法2,在标签体中指定格式化文本串中的占位符参数的情况: [bundle="resourceBundle"] [var="varName"] [scope="{page|request|session|application}"]>
语法3,在标签体中指定消息关键字和可选择的占位符参数: [var="varName"] [scope="{page|request|session|application}"]> key optional
表8.15 属性名 是否支持EL 属性类型 属 性 描 述 key true String 指定要输出的信息的关键字 bundle true LocalizationContext 指定ResourceBundle对象在Web域中的属性名称 var false String 用于指定将格式化结果保存到某个Web域中的某个属性的名称 scope false String 指定将格式化结果保存到哪个Web域中 例程8-30是一个使用 例程8-30 fmt_message.jsp <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=gb2312" %> <% session.setAttribute("number", new Integer(8888888)); %> <fmt:message>标签内嵌套<fmt:param>标签的情况: org.it315.okKey <fmt:message>标签内没有嵌套<fmt:param>标签的情况: 例程8-30的运行结果如图8.25 所示。
图8.25 语法1,用value属性指定参数值: 语法2,在标签体中指定参数的值的情况: body content
说明: 其中的value属性用于指定请求消息的字符集编码,其类型为String,支持动态属性值。 关于 (1)为了能够正确解码请求参数值中的非ISO-8859-1编码的字符,应该调用这个标签来设置请求消息的字符集编码,并且必须在获取任何请求参数(包括使用EL表达式获取参数)之前进行调用。 (2)因为很多浏览器没有完全遵守HTTP规范,在请求消息中没有包含Content-Type请求头,所以使用这个标签来设置请求消息的字符集编码是很有必要的。 (3) 例程8-31是一个使用 例程8-31 fmt_requestEncoding.jsp <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=gb2312" %> 我最喜欢的科目是:${param.favourite}
你最喜欢学习的是什么科目?
例程8-31的运行结果如图8.26所示,在文本框中输入“英语”,单击其中的OK按钮后的运行结果如图8.27所示。
图8.26
图8.27 body content
其中的value属性支持动态属性值,它的值可以是一个命名时区的字符串,也可以是java.util.TimeZone类的一个实例对象。如果value属性的值为null或空字符串,标签体中的内容就使用GMT的0基准时区。如果value属性的值是表示时区名称的字符串,这个字符串通过java.util.TimeZone.getTimeZone()静态方法被解析为java.util.TimeZone类的实例对象。 例程8-32是一个使用 例程8-32 fmt_timeZone.jsp <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=gb2312" %> <%@ page import="java.util.TimeZone" %> 使用“GMT+1:00”时区: <% TimeZone tz = TimeZone.getDefault(); pageContext.setAttribute("tz", tz); %> 使用默认的时区,value为java.util.TimeZone的一个实例: 使用“America/Los_Angeles”时区:
例程8-32的运行结果如图8.28 所示。
图8.28 [var="varName"] [scope="{page|request|session|application}"] /> 表8.16 属性名 是否支持EL 属性类型 属 性 描 述 value true String或java.util.TimeZone 指定表示时区的ID字符串或TimeZone对象 var false String 指定将创建出的TimeZone实例对象保存到Web域中的属性名称 scope false String 指定将创建出的TimeZone实例对象保存到哪个Web域中 其中,value属性的设置值的细节与 例程8-33是一个使用 例程8-33 fmt_setTimeZone.jsp <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=gb2312" %> “America/Los_Angeles”时区的现在时间是: “GMT+1:00”时区的现在时间是:
例程8-33的运行结果如图8.29所示。
图8.29 [type="{time|date|both}"] [dateStyle="{default|short|medium|long|full}"] [timeStyle="{default|short|medium|long|full}"] [pattern="customPattern"] [timeZone="timeZone"] [var="varName"] [scope="{page|request|session|application}"] /> 表8.17 属性名 是否支持EL 属性类型 属 性 描 述 value true java.util.Date 指定要格式化的日期或时间 type true String 指定是格式化输出日期部分,还是格式化输出时间部分,还是两者都输出 dateStyle true String 指定日期部分的输出格式,其可用的设置值可以参照java.text.DateFormat类的讲解。该属性仅在type属性取值为date或both时才有效 timeStyle true String 指定时间部分的输出格式,其可用的设置值请参照java.text.DateFormat类的讲解。该属性仅在type属性取值为time或both时才有效 pattern true String 指定一个自定义的日期和时间输出格式 timeZone true String或java.util.timeZone 指定当前采用的时区 var false String 用于指定将格式化结果保存到某个Web域中的某个属性的名称 scope false String 指定将格式化结果保存到哪个Web域中 例程8-34是一个使用 例程8-34 fmt_formatDate.jsp <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=gb2312" %> <%@ page import="java.util.TimeZone" %> 格式化当前日期、时间: <% session.setAttribute("tz", TimeZone.getTimeZone("GMT+10")); %> 指定时区为“GMT+10”: 指定自定义的格式,月.日.年: 格式化用字符串表示的日期: 例程8-34的运行结果如图8.30 所示。
图8.30 语法1,没有标签体的情况: [type="time|date|both"] [dateStyle="default|short|medium|long|full"] [timeStyle="default|short|medium|long|full"] [pattern="customPattern"] [timeZone="timeZone"] [parseLocale="parseLocale"] [var="varName"] [scope="{page|request|session|application}"] /> 语法2, 有标签体的情况,在标签体中指定要被解析的日期和/或时间值: [dateStyle="default|short|medium|long|full"] [timeStyle="default|short|medium|long|full"] [pattern="customPattern"] [timeZone="timeZone"] [parseLocale="parseLocale"] [var="varName"] [scope="{page|request|session|application}"]> date value to be parsed 表8.18
在前面的例程8-34中已经使用了 语法1,没有标签体的情况: [type="{number|currency|percent}"] [pattern="customPattern"] [currencyCode="currencyCode"] [currencySymbol="currencySymbol"] [groupingUsed="{true|false}"] [maxIntegerDigits="maxIntegerDigits"] [minIntegerDigits="minIntegerDigits"] [maxFractionDigits="maxFractionDigits"] [minFractionDigits="minFractionDigits"] [var="varName"] [scope="{page|request|session|application}"] /> 语法2,有标签体的情况,在标签体中指定要被格式化的数值: [pattern="customPattern"] [currencyCode="currencyCode"] [currencySymbol="currencySymbol"] [groupingUsed="{true|false}"] [maxIntegerDigits="maxIntegerDigits"] [minIntegerDigits="minIntegerDigits"] [maxFractionDigits="maxFractionDigits"] [minFractionDigits="minFractionDigits"] [var="varName"] [scope="{page|request|session|application}"]> 要被格式化的数值
如果指定scope属性,就必须指定var属性。 表8.19
例程8-35是一个使用 例程8-35 fmt_formatNumber.jsp <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=gb2312" %> <%@ page import="java.util.Currency,java.util.Locale"%> 将数值格式化为货币格式: 将数值格式化为百分数格式: 将数值格式化为自定义的格式: <% String code = Currency.getInstance(Locale.CHINA).getCurrencyCode(); String symbol = Currency.getInstance(Locale.US).getSymbol(); session.setAttribute("code", code); session.setAttribute("symbol", symbol); %> 同时指定currencyCode和currencySymbol属性,前者优先于后者: currencySymbol="${symbol}" /> 例程8-35的运行结果如图8.31 所示。
图8.31 语法1,没有标签体的情况: [type="{number|currency|percent}"] [pattern="customPattern"] [parseLocale="parseLocale"] [integerOnly="{true|false}"] [var="varName"] [scope="{page|request|session|application}"] /> 语法2,有标签体的情况,在标签体中指定要被解析的数值: [pattern="customPattern"] [parseLocale="parseLocale"] [integerOnly="{true|false}"] [var="varName"] [scope="{page|request|session|application}"]> numeric value to be parsed
表8.20
例程8-36是一个使用 例程8-36 fmt_parseNumber.jsp <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=gb2312" %> 本地环境为“en_US”解析字符串“$123,456,789.00”: 解析整个数值字符串“123,456,789%”: 只解析“123,456,789%”的整数部分: 同时设置type和pattern属性,后者优先于前者: 例程8-36的运行结果如图8.32 所示。
图8.32 注意:在分层设计的软件架构中,JSP页面通常仅用于实现系统的表示层,数据解析的任务不适合在表示层进行处理,而最好是业务逻辑层进行处理,所以,为了增强软件的易维护性和可扩展性,读者应尽量避免在JSP 页面中使用
图8.39 为了简化在JSP页面操作字符串,JSTL中提供了一套EL自定义函数,这些函数包含了JSP页面制作者经常要用到的字符串操作。例如,fn:toLowerCase将字符串中的字符变为小写,fn:indexOf返回一个指定字符串在另一个字符串中第一次出现的索引位置。 JSTL中提供的EL自定义函数必须在EL表达式中使用,例如,${fn:toUpperCase("www.it315.org")}。 fn:toLowerCase函数将一个字符串中包含的所有字符转换为小写形式,并返回转换后的字符串,它接收一个字符串类型的参数。 fn:toLowerCase函数的应用举例: fn:toUpperCase函数将一个字符串中包含的所有字符转换为大写形式,并返回转换后的字符串,它接收一个字符串类型的参数。 fn:toUpperCase函数的应用举例: fn:trim函数删除一个字符串的首尾的空格,并返回删除空格后的结果字符串,它接收一个字符串类型的参数。需要注意的是,fn:trim函数不能删除字符串中间位置的空格。 例如,fn:trim(" www.it 315.org ") 的返回值为字符串“www.it 315.org”。 fn:escapeXml函数将字符串中的需要进行转义的HTML特殊字符按表8.2进行HTML编码转换,并返回转换后的字符串,这样就可以在浏览器中显示出HTML特殊字符。fn:escapeXml函数接收一个字符串类型的参数。 例如,运行包含如下代码的JSP文件后浏览器将跳转到“http://www.it315.org”页面,这是因为这些代码被浏览器作为HTML标签解释执行: "refresh" content="0;url=http://www.it315.org"/> 如果用fn:escapeXml函数处理上面的代码,运行JSP文件后就在浏览器窗口输出这行代码,例程8-54是使用fn:escapeXml函数处理上面的代码的例子程序。 例程8-54 fn_escapeXml.jsp <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> ${fn:escapeXml(' content="0;url=http://www.it315.org"/>')} fn_escapeXml.jsp页面的运行结果如图8.46所示。
图8.46 fn:length函数用于返回一个集合或数组对象中包含的元素的个数,或返回一个字符串中包含的字符的个数,返回值为int类型。fn:length函数接收一个参数,这个参数可以是 如果fn:length函数的参数为null或者是元素个数为0的集合或数组对象,则函数返回0;如果参数是空字符串,则函数返回0。例程8-55是使用fn:length函数的实例程序。 例程8-55 fn_length.jsp <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> <%@ page contentType="text/html;charset=gb2312" %> <%@ page import="java.util.*, org.it315.UserBean" %> <% Collection users = new ArrayList(); for(int i=0; i<5; i++) { UserBean user = new UserBean(); user.setUserName("user" + i); user.setPassword("guest" + i); users.add(user); } session.setAttribute("users", users); %> There are ${fn:length(users)} users online. 字符串“www.it315.org”中包含 ${fn:length("www.it315.org")} 个字符 fn_length.jsp页面的运行结果如图8.47所示。
图8.47 fn:split函数以指定字符串作为分隔符,将一个字符串分割成字符串数组并返回这个字符串数组。fn:split函数接收两个字符串类型的参数,第一个参数表示要分割的字符串,第二个参数表示作为分隔符的字符串。 fn:join函数以一个字符串作为分隔符,将一个字符串数组中的所有元素合并为一个字符串并返回合并后的结果字符串。fn:join函数接收两个参数,第一个参数是要操作的字符串数组,第二个参数是作为分隔符的字符串。 如果fn:join函数的第二个参数是空字符串,则fn:join函数的返回值是不使用任何分隔符将字符串数组中的各元素连接起来的结果字符串。 fn:join函数的应用举例: fn:indexOf函数返回指定字符串在一个字符串中第一次出现的索引值,返回值为int类型。fn:indexOf函数接收两个字符串类型的参数,如果第一个参数字符串中包含第二个参数字符串,那么,不管第二个参数字符串在第一个参数字符串中出现几次,fn:indexOf函数总是返回第一次出现的索引值;如果第一个参数中不包含第二个参数,则fn:indexOf函数返回-1。如果第二个参数为空字符串,则fn:indexOf函数总是返回0。 fn:indexOf函数的应用举例: fn:contains函数检测一个字符串中是否包含指定的字符串,返回值为布尔类型。fn:contains函数在比较两个字符串是否相等时是大小写敏感的。 fn:contains函数接收两个字符串类型的参数,如果第一个参数字符串中包含第二个参数字符串,则fn:contains函数返回true,否则返回false。如果第二个参数的值为空字符串,则fn:contains函数总是返回true。实际上,fn:contains(string, substring)等价于fn:indexOf(string, substring) != -1。 fn:contains函数的应用举例: fn:containsIgnoreCase函数检测一个字符串中是否包含指定的字符串,在比较两个字符串是否相等时大小写不敏感。fn:containsIgnoreCase函数的参数和返回值的类型都与fn:contains函数相同,只是前者在比较两个字符串是否相等时不考虑字符的大小写,而后者考虑字符的大小写,fn:containsIgnoreCase(string, substring)等价于fn:contains(fn:toUpperCase(string),fn:toUpperCase(substring))。 fn:containsIgnoreCase函数的应用举例: fn:startsWith函数用于检测一个字符串是否是以指定字符串开始的,返回值为布尔类型。 fn:startsWith函数接收两个字符串类型的参数,如果第一个参数字符串以第二个参数字符串开始,则函数返回true,否则函数返回false。如果第二个参数为空字符串,则fn:startsWith函数总是返回true。实际上,fn:startsWith(string, prefix)等价于表达式fn:indexOf(string, prefix) == 0。 fn:startsWith函数的应用举例: fn:endsWith函数用于检测一个字符串是否是以指定字符串结束的,返回值为布尔类型。 fn:endsWith函数接收两个字符串类型的参数,如果第一个参数字符串以第二个参数字符串结束,则函数返回true,否则函数返回false。如果第二个参数为空字符串,则fn:endsWith函数总是返回true。 fn:endsWith函数的应用举例: fn:replace函数将一个字符串中包含的指定子字符串替换为其它的指定字符串,并返回替换后的结果字符串。fn:replace方法接收三个字符串类型的参数,第一个参数表示要操作的源字符串,第二个参数表示源字符串中要被替换的子字符串,第三个参数表示要被替换成的字符串。 fn:replace函数按照下面的说明执行字符串的替换操作: (1)源字符串中所有的第二个参数指定的子字符串都被替换成第三个参数指定的字符串,如果替换后的结果字符串中包含第二个参数指定的子字符串,则不再进行替换。例如, (2)如果第一个参数是空字符串,则fn:replace函数返回空字符串,例如,fn:replace("", " ", ".")的返回值为空字符串。 (3)如果第二个参数是空字符串,则fn:replace函数不执行任何替换操作,返回第一个参数指定的字符串。例如,fn:replace("www.it315.org", "", " ") 的返回值为字符串“www.it315.org”。 (4)如果第三个参数是空字符串,则fn:replace函数删除源字符串中包含的第二个参数指定的子字符串。例如,fn:replace("www.it315.org", ".", "")的返回值为字符串“wwwit315org”。 fn:substring函数用于截取一个字符串的子字符串并返回截取到的子字符串。fn:substring函数接收三个参数,第一个参数是用于指定要操作的源字符串,第二个参数是用于指定截取子字符串开始的索引值,第三个参数是用于指定截取子字符串结束的索引值,第二个参数和第三个参数都是int类型,其值都从0开始。 fn:substring函数按照下面的说明截取一个字符串的子字符串: fn:substring函数的应用举例(字符串“www.it315.org”中包含13个字符): fn:substringAfter函数用于截取并返回一个字符串中的指定子字符串第一次出现之后的子字符串。fn:substringAfter函数接收两个字符串类型的参数,第一个参数表示要操作的源字符串,第二个参数表示指定的子字符串,例如,fn:substringAfter("www.it315.org", ".")的返回值为字符串“it315.org”。 fn:substringAfter函数按照下面的说明截取一个字符串的子字符串: fn:substringBefore函数用于截取并返回一个字符串中的指定子字符串第一次出现之前的子字符串。fn:substringBefore函数接收两个字符串类型的参数,第一个参数表示要操作的源字符串,第二个参数表示指定的子字符串,例如,fn:substringBefore("www.it315.org", ".") 的返回值为字符串“www”。 fn:substringBefore函数按照下面的说明截取一个字符串的子字符串: 思考题: 1、请用 2、请用 3、请嵌套调用 4、 请在EL表达式用JSTL函数fn:split和fn:length取出字符串"a/b/c/d.txt"中的最后一个"/"后面的内容。 number count even|odd ${i} ${status.count}
8.3.8
8.3.9 URL相关的标签概述
8.3.10
8.3.11
8.3.12
8.3.13
8.4 国际化标签
8.4.1 国际化标签库概述
8.4.2
8.4.3
8.4.4
8.4.5
8.4.6
8.4.7
8.4.8
8.4.9
8.4.10
8.4.11
8.4.12
8.4.13
8.7 JSTL函数
8.7.1 fn:toLowerCase函数
8.7.2 fn:toUpperCase函数
8.7.3 fn:trim函数
8.7.4 fn:escapeXml函数
8.7.5 fn:length函数
8.7.6 fn:split函数
8.7.7 fn:join函数
8.7.8 fn:indexOf函数
8.7.9 fn:contains函数
8.7.10 fn:containsIgnoreCase函数
8.7.11 fn:startsWith函数
8.7.12 fn:endsWith函数
8.7.13 fn:replace函数
8.7.14 fn:substring函数
8.7.15 fn:substringAfter函数
8.7.16 fn:substringBefore函数
你可能感兴趣的:(jsp)