JSTL标签库

  JSTL是Sun公司开发的一套用于JSP页面中的标签库,使用JSTL可以在页面中实现一些简单的逻辑,从而替换页面中的Java代码。JSTL通常也会配合EL表达式一起使用,Sun公司的JSTL标签库封装了大量的方法,当然如果JSTL中的标签不能满足我们的需求时,我们还可以通过使用自定义标签达到我们的需求,关于自定义标签会在之后的文章中讲解。

  JSTL标签库是一个很大的库,主要包含了以下几种:

  ⑴ JSTL核心标签库——c.tld

  ⑵ 国际化标签——fmt.tld

  ⑶ JSTL函数(EL函数)——fn.tld

  ⑷ 数据库标签  (不符合MVC模式,不用学)——sql.tld

  ⑸ XML标签 (不符合MVC模式,不用学)——x.tld

 

  JSTL函数已经在《EL表达式(3)》中学习过,这里就不再叙述;国际化标签会在之后的文章中讲解和学习。今天主要来学习JSTL核心标签库。

 

  在MyEclipse10中,创建JavaEE 5.0以上的版本都会默认带上JSTL开发包,并且使用的是JSTL1.2版本:

  JSTL标签库_第1张图片

  而如果创建的是J2EE 1.4及以下的版本,需要自己选择是否添加JSTL支持,并且如果选择添加,那么导入的是JSTL1.1版本:

  JSTL标签库_第2张图片

  JSTL1.2版本和JSTL1.1的版本在JAR包上的区别是JSTL1.2只需要“jstl-1.2.jar”一个包就足够了,而JSTL1.1需要“jstl.jar”包和“standard.jar”包的支持。如果我们在工程中缺少相对应的包,只需要选择合适的jar包导入即可。

  当然,这只是外部版本的区别,其实不管是JSTL1.2版本还是JSTL1.1的版本,对于JSTL核心标签库都是使用“JSTL 1.1 core library”,我想区别可能是另外几个库吧。

在本篇中,我们均是以Java EE 5.0为WEB的Java版本,因此均采用JSTL1.2版本。

 

  除了要导入需要的jar包,要想使用JSTL标签,还必须在JSP页面中使用taglib指令导入需要的标签库。

语法:

    <%@ taglib uri="。。。" prefix="。。。" %>

  uri属性:用来指定使用JSTL标签库中的哪个标签库。

  prefix属性:用来指定在JSP页面中使用该标签的前缀文字。

   那么如何使用uri属性来指定使用哪个标签库呢?我们可以点击工程中的“jstl-1.2.jar”包:

  JSTL标签库_第3张图片

  这个jar包中有很多包和类,在最下面有一个“META-INF”目录,这里面保存了很多标签所需要的tld文件,分别代表不同的库,而我们所需要的jstl核心库就是“c.tld”文件:

  JSTL标签库_第4张图片

  对于jstl核心库的所有标签,都在这个“c.tld”文件中进行了声明描述。而这些所有的标签都绑定到了一个uri上,通过在JSP中使用taglib指令导入这个uri,那么我们就能使用这个标签库了,而这个uri就在“c.tld”文件的<taglib>标签下:

  JSTL标签库_第5张图片

因此我们在JSP页面中使用taglib指令就可以这样导入该标签库:

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

  这里taglib指令中的uri一定要和tld文件中的uri一致,而prefix前缀通常采用tld文件的文件名,这样容易明白这个标签出自哪个JSTL库。

  通过以上步骤,JSTL标签库的环境就已经配置好了,接下来我们就可以使用JSTL的核心库标签了。

  补充前言:标签中如果含有“var”属性,就是讲该标签的执行结果以“var”属性的值存储到某个域中,通常都会有“scope”属性来指定存储到哪个域中,如果没有一般都是存储到page域中。

  下面介绍几个JSTL核心标签库中的几个标签的使用,较为常用的有前面三个:

一.<c:forEach>标签

使用<c:forEach>标签可以配合EL表达式对使用EL获取的集合进行迭代,这一点光凭EL表达式是无法做到的。

例1-1:

 1     <%
 2            ArrayList<Person> list = new ArrayList<Person>();
 3            list.add(new Person("Ding",25));
 4            list.add(new Person("LRR",24));
 5            pageContext.setAttribute("personList", list);
 6     %>
 7     
 8     <c:forEach var="person" items="${personList}">
 9         ${person.name }  <br>
10 </c:forEach>
View Code

  分析:这个例子中在<c:forEach>标签内,“items”属性用于指定获取迭代的对象。记住,这里一定要用EL表达式才能获取存储在域中的对象。而“var”属性则是对每次迭代的元素以var的值为关键字存在域中,就好像使用了Map集合一样,对集合中的每个元素作为value值,而“var”名称作为key一样。

  在上面的示例中,items通过EL表达式获取域对象中的“list”集合,而对“list”集合的每次迭代都是一个Person对象,这个Person对象使用了var属性指定的值作为引用。因此在标签体中,再次使用了EL表达式,而这个EL表达式中的“person”既是var属性所指的名称,也是每次迭代的Person对象的引用,而Person对象中含有name属性,因此可以使用EL表达式取出,这点与之前学过的EL获取数据还是一样的道理。在浏览器中观察:

  JSTL标签库_第6张图片

例1-2:

 1     <%
 2            Map<String,Person> map = new HashMap<String,Person>();
 3            map.put("p1",new Person("Ding",25));
 4            map.put("p2",new Person("LRR",24));
 5            pageContext.setAttribute("personMap", map);
 6     %>
 7     
 8     <c:forEach var="entry" items="${personMap}">
 9         ${entry.value.name }  <br>
10     </c:forEach>
View Code

  分析:在这个例子中,“items”属性依然还是获取要迭代的对象(使用EL表达式才能获取域对象中保存的要迭代的集合对象)。而这里我们使用<c:forEach>标签并不是真正对Map集合进行迭代,而是将Map集合先调用了entrySet方法,获取到的是Set<Map.Entry<K,V>>集合,然后再对这个Set集合进行迭代:

  

  那么也就是说对于“var”属性,指定的都是对Set集合进行迭代出来元素的引用,而Set集合迭代出来的每个元素都是Map.Entry集合,即以“var”名称所引用。因此上述示例中的var属性的值“entry”代表了每次迭代出来的Map.Entry集合,而这个Map.Entry集合中含有key属性和value属性(通过API可以看到含有getKey方法和getValue方法),因此在标签体中,${entry.value}代表了存在Map集合中的Person对象,另外${entry.key}代表了Map集合中Person对象所被引用的key值(如”p1”)。

在浏览器中观察:

  JSTL标签库_第7张图片

  通过上面两个例子,可以大体了解了<c:forEach>标签的使用,当然<c:forEach>标签还有一些需要了解的地方:

  JSTL标签库_第8张图片

例1-3:

1     <c:forEach var="num" begin="1" end="9" step="1" >
2         ${num }
3     </c:forEach>
View Code

浏览器观察:

  JSTL标签库_第9张图片

可以看到在<c:forEach>标签中,如果没有“items”属性,那么就从begin属性指定的值开始迭代,直到end属性指定的值为止,而“var”属性依然是作为每次迭代出来元素的引用。

 

  在<c:forEach>标签中还有一个“varStatus”属性,这个属性用来封装保存迭代信息的对象,比如这是第几个迭代对象,是否是第一个迭代对象,是否是最后一次迭代对象等等,在“varStatus”属性下,还有属于varStatus的几个从属性,这些可以配合EL表达式使用:

  index:当前这次迭代从 0 开始的迭代索引

  count:当前这次迭代从 1 开始的迭代计数

  first:用来表明当前这轮迭代是否为第一次迭代的标志

  last:用来表明当前这轮迭代是否为最后一次迭代的标志

  begin:属性值

  end:属性值

  step:属性值

 

例1-4:

 1     <%
 2            ArrayList<Person> list = new ArrayList<Person>();
 3            list.add(new Person("Ding",25));
 4            list.add(new Person("LRR",24));
 5            
 6            pageContext.setAttribute("personList", list);
 7        %>
 8        
 9     <c:forEach var="person" items="${personList }" varStatus="listInfo" >
10         ${person.name } ---- ${listInfo.count }   <br>
11     </c:forEach>
View Code

浏览器中观察:

  JSTL标签库_第10张图片

  这里使用到的是”varStatus”属性的从属性“count”,用来表示当前这次迭代从 1 开始的迭代计数。其他的从属性都是类似的用法。

 

二.<c:if>标签

  <c:if  test=“。。。”>标签(test属性是必须的)用于测试某个条件是否成立,经常配合EL表达式使用。

  JSTL标签库_第11张图片

例2-1:

1     <c:if test="${user!=null}">
2         欢迎您:user.name
3     </c:if>
View Code

  分析:“test”属性只接收布尔类型,当“test”属性为“true”时才执行<c:if>标签的标签体中的内容,当“test”属性为“false”时标签体内容自动忽略。

 

例2-2:

1     <c:if var="booleanTest" test="${user!=null}" scope="page">
2         欢迎您:user.name
3     </c:if>  
4     
5     ${booleanTest }
View Code

输出:false

  分析:“test”属性返回Boolean性结果(true或false),“var”属性均是作为存储数据用的,这里是将“test”属性的结果以“var”属性的值(这里是booleanTest)存储到某个域中,存到什么域呢,由“scope”属性指定。这样最后能由EL表达式从域中根据“var”属性的值取出相对应的数据。

  总结:只要某个标签含有“var”属性,就是讲该标签的执行结果以“var”属性的值存储到某个域中,通常都会有“scope”属性来指定存储到哪个域中,如果没有一般都是存储到page域中。

 

三.<c:url>标签与<c:param>标签

  <c:url>标签用于在JSP页面中创建一个URL地址,最关键的目的在于<c:url>标签能对其“value”属性提供的URL地址进行重写,加入JSESSIONID,以便于在访问禁用cookie的主机能为其创建session等功能。这一点在《Servlet的学习之Session(3)》 中已经介绍过。

  下图为<c:url>标签中的属性介绍:

  JSTL标签库_第12张图片

例3-1:

1     <c:url var="index" value="${pageContext.request.contextPath}/index" />
2     
3     <a href="${index}" >首页</a>
View Code

浏览器观察:

  JSTL标签库_第13张图片

查看网页源码:

  

  可以看到在首次访问时确实在URL后面跟了JSESSIONID,这是<c:url>标签用于防止客户浏览器禁止了Cookie,同样的,如果服务器发现了客户机浏览器并没有禁用cookie的话,那么再次访问的话,<c:url>标签会将这个JSESSIONID会自动删去,这一点同使用Response.encodeURL()方法或Response.encodeRedirectURL()方法是一样的。

  另外:<c:url>标签中使用了“var”属性,就是将“value”中的URL进行重写后保存在域中(默认为page域,可用“scope”选择域)。那么在其他HTML标签中如果有需要URL的超链接时,只需要使用EL表达式从域中取出即可,取出的即使经过URL重写的超链接URL,正如上面的例子。

 

例3-2:

<c:url value="/index" />

在浏览器中观察:

  JSTL标签库_第14张图片

  如果没有使用到“var”属性,那么这个标签会将内容直接显示在网页中,这一点要注意。同时该注意的还有这种没有“var”属性,会自动在URL前面添加web应用的名称!所以在没有使用“var”属性的<c:url>标签中的“value”属性一定不要添加web应用的名称。

 

例3-3:

    <a href='<c:url value="/index" />'>首页</a>

在浏览器中观察及网页源码:

  JSTL标签库_第15张图片

  通常<c:url>标签还配合<c:param>标签一起使用。使用<c:param>标签可以在URL后面添加请求参数,更为重要的一点在于,使用<c:param>标签能对参数中的中文进行URL重写,这一点在《Servlet的学习之Request请求对象(2)》中说明了另一种解决方法。

 

例3-4:

1 <c:url var="index" value="${pageContext.request.contextPath}/index.jsp" >
2     <c:param name="username" value="银魂"></c:param>
3 </c:url>
4     
5 <a href="${index}">首页</a>
View Code

在浏览器中观察及其网页源码:

  JSTL标签库_第16张图片

  可以看到在网页源码中,URL地址后面已经跟随了请求参数,同时当请求参数中包含中文时也对中文进行了URL重写。

 

四.<c:out>标签

  JSTL标签库_第17张图片

例2-1:

    <c:out value="aaaa" />

输出:aaaa。

 

例2-2:

    <c:out value="<a href='www.baidu.com'>百度</a>" escapeXml="true" />

输出:

  JSTL标签库_第18张图片

 

五.<c:set>标签

  <c:set>标签用于把一个对象或数据存在指定的域范围内,或者设置web域中的java.util.Map类型的属性对象,或者JavaBean类的属性对象的属性。

  JSTL标签库_第19张图片

例4-1:

1     <c:set var="name" value="ding" scope="page" />
2     
3     ${name }
View Code

输出:ding。

 

例4-2:

1     <%
2            HashMap map = new HashMap();
3            pageContext.setAttribute("map", map);
4     %>
5    
6     <c:set property="name" value="ding" target="${map}" ></c:set>
7     
8        ${map.name }
View Code

输出:ding。

 

例4-3:

1     <%
2        Person p = new Person();
3            pageContext.setAttribute("person", p);
4     %>
5    
6     <c:set property="age" value="25" target="${person}" ></c:set>
7     
8        ${person.age }
View Code

输出:25

 

六.<c:remove>标签

  <c:remove>标签用于移除web域中的各种保存的数据。

语法格式:

    <c:remove    var=”保存的数据引用名”
                [scope=“{ page(默认) | request | session | application }”] />

 

七.<c:redirect >标签

  <c:redirect>标签用于进行网页的重定向。

  JSTL标签库_第20张图片

 

你可能感兴趣的:(JSTL标签库)