概述
本篇博文中主要探讨以下内容:
- JSTL的核心标签库的使用
- 开发简单的自定义标签的步骤
- 在Web应用中使用标签
JSTL和自定义标签
- 一、JSTL
- 1.1 通用目的标签
- 1.1.1 out标签
- 1.1.2 set标签
- 1.1.3 remove标签
- 1.2条件控制标签
- 1.2.1 if标签
- 1.2.2 choose标签
- 1.3 循环控制标签
- 1.3.1 forEach标签
- 二、自定义标签
- 2.1 创建"Hello"标签
- 2.2 访问标签体
- 2.3 自定义标签属性
一、JSTL
- JSTL(JSP Standard Tag Library):JSP标准标签库
使用JSTL可以提高JSP页面的开发效率,也可以避免重复开发标签库。
- JSTL包
taglibs-standard-impl-1.2.5.jar
taglibs-standard-spec-1.2.5.jar
下载地址:
http://tomcat.apache.org/download-taglibs.cgi
- JSTL库及使用的URI与前缀
库名称 | 使用的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 |
SQL标签库 | http://java.sun.com/jsp/jstl/sql | sql |
函数库 | http://java.sun.com/jsp/jstl/functions | fn |
- 核心(core)标签库
- 通用目的
<c:out>//在页面中显示内容
<c:set>//定义或者设置一个作用域变量值
<c:remove>//清除一个作用域变量
<c:catch>//捕获异常
- 条件控制
<c:if>//根据一个属性等于一个值改变处理
<c:choose>//根据一个属性等于一组值改变处理
<c:when>//用来测试一个条件
<c:otherwise>//当所有when条件都为false时,执行该标签内的内容
- 循环控制
<c:forEach>//对集合中的每个对象作迭代处理
<c:forTokens>//对给定字符串中的每个子串执行处理
- URL处理
<c:url>//重写URL并对它们的参数编码
<c:import>//访问Web应用程序外部的内容
<c:redirect>//告诉客户浏览器访问另一个URL
<c:param>//用来传递参数
在JSP页面中使用JSTL,必须使用taglib指令来引用标签库
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
1.1 通用目的标签
1.1.1 out标签
<c:out>标签的功能与JSP中脚本表达式(<%= %>)相同,用于向页面输值。
- 格式一:不带标签体
<c:out value="$value" [escapeXml ="{true|false}"]
default = "defaultValue"/>
- 格式二:带标签体
<c:out value="$value" [escapeXml ="{true|false}"]>
default value
</c:out>
标签需要一个value属性,它的值是向页面中输出的值。default表示如果value的值为null或者不存在,则输出该默认值;如果escapeXml的值为true(默认值),表示将value属性值中包含的<,>,’,"或者&等特殊字符转换为相应的实体引用(或者字符编码),如小于号(<)将转换为<;大于号(>)转换为>;如果escapeXml的值为false将不转换。
<c:out value ="${[pageContext.request.remoteAddr}" /> //输出客户地址
<c:out value ="${number} /> //输出number变量的值
//可以替换JSP的脚本表达式
1.1.2 set标签
尽管EL可以有很多方式管理变量,单不能定义作用域变量和从作用域中删除变量。使用<c:set>和<c:remove>标签,就能完成这些操作哟。
使用<c:set>标签可以:
- 定义一个字符串类型的作用域变量,并通过变量名引用它。
- 通过变量名引用一个现有的作用域变量。
- 重新设置作用域变量的属性值
作用:向域对象中存入值
- 属性:
var:key值
value:值
scope:作用域(page request session application) - 代码:
<h3>set标签</h3>
<%
request.setAttribute("msg", "A");
%>
<c:set var="msg" value="B" scope="request"></c:set>
${ msg }
//页面输出结果:B
另外一种格式
//不带标签体的情况 单标签
<c:set target = "target" property="propertyName" value = "value" />
或者
//带标签体的情况 双标签标签
<c:set target = "target" property="propertyName">
value
</c:set>
//其中 target属性是指定对象名
property属性是指定属性名
value属性是要设置的值
注意:target属性的值应该是用EL的形式,如target="${book}",不能写成
target="book"
1.1.3 remove标签
- 作用:从域对象中移除值
- 属性:
var:移除的key值 - 代码:
<h3>remove标签</h3>
<c:set var="msg" value="美美"/>
${ msg }
<h3>已经把msg移除了</h3>
<c:remove var="msg"/>
${ msg }
注意:remove标签不能用于删除JavaBeans或Map对象
1.2条件控制标签
1.2.1 if标签
- 作用:进行语句的判断。注意:只有if,没有else
- 属性:
test:必须要出现的,判断的条件
var:把判断条件的结果(true或者false)保存到var变量中
scope:作用域
代码:
<h3>if标签</h3>
<%
int n = 20;
request.setAttribute("n", n);
%>
<c:if test="${ n eq 10 }" var="i">
<font color="red">n=10</font>
</c:if>
<c:if test="${ n ne 10 }">
<font color="blue">n!=10</font>
</c:if>
${ i }
页面输出结果:n!=10 false
1.2.2 choose标签
- 作用:用来进行判断,但是复合的标签
<c:choose>
<c:when test=""></c:chen>
<c:when test=""></c:chen>
<c:otherwise></c:otherwise>
</c:choose>
- 属性:
关注when标签,test属性 - 代码:
<%
int n = 10;
request.setAttribute("n", n);
%>
<c:choose>
<c:when test="${ n eq 20 }">
n=20
</c:when>
<c:otherwise>
n=其他
</c:otherwise>
</c:choose>
页面输出结果:n=其他
1.3 循环控制标签
1.3.1 forEach标签
- 作用:用来迭代数据
forEach当成普通的for循环。for(int i=1; i<=10; i++){}
forEach当成增强的for循环。for(String key : 集合){} - 属性:
var:声明变量
begin:从哪开始
end:到哪结束
step:步长
varStatus:在迭代的过程中会产生一些信息,把信息保存在varStatus属性。其中属性有一些值:
count:代表计数
index:代表下标
first:判断是否是第一个元素
last:判断是否是最后一个元素
current:代表当前迭代的元素
items:代表的是要迭代的集合(数组 list set map) - 代码:
<%@page import="com.pers.domain.User"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 导入JSTL的标签库 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
for(int i=0;i<=10;i++){
}
%>
<h3>普通for循环</h3>
<c:forEach var="j" begin="0" end="10" step="1" varStatus="vs">
${ vs.count }
</c:forEach>
<h3>模拟增强for循环</h3>
<c:forEach var="s" items="${ list }">
${ s }
</c:forEach>
<h3>遍历数据,数据需要存入在域对象中,遍历List集合</h3>
<%
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
request.setAttribute("list", list);
%>
<c:forEach var="s" items="${ list }">
${ s }
</c:forEach>
<h3>遍历Map集合</h3>
<%
Map<String,String> map = new HashMap<String,String>();
map.put("a", "A");
map.put("b", "B");
map.put("c", "C");
request.setAttribute("map", map);
%>
<c:forEach var="entry" items="${ map }">
${ entry.key } -- ${ entry.value }
</c:forEach>
<h3>List集合中有Java对象</h3>
<%
List<User> ulist = new ArrayList<User>();
ulist.add(new User(1,"张三","zhangsan123","zhangsan@163.com"));
request.setAttribute("ulist", ulist);
%>
<c:forEach var="user" items="${ ulist }">
${ user.username } -- ${ user.email }
</c:forEach>
</body>
</html>
二、自定义标签
自定义标签是用户定义的JSP语言元素。当JSP页面包含一个自定义标签时将被转化为servlet,标签转化为对被 称为tag handler的对象的操作,即当servlet执行时Web container调用那些操作。
JSP标签扩展可以让你创建新的标签并且可以直接插入到一个JSP页面。 JSP 2.0规范中引入Simple Tag Handlers来编写这些自定义标记。
你可以继承SimpleTagSupport类并重写的doTag()方法来开发一个最简单的自定义标签。
开发简单的自定义标签的步骤
(1)创建标签处理类
(2)创建标签库描述文件TLD
(3)在JSP页面中使用标签
2.1 创建"Hello"标签
接下来,我们想创建一个自定义标签叫作
<ltex:Hello>
标签格式为:
<ex:Hello />
要创建自定义的JSP标签,你首先必须创建处理标签的Java类。所以,让我们创建一个HelloTag类,如下所示:
package com.runoob;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
JspWriter out = getJspContext().getOut();
out.println("Hello Custom Tag!");
}
}
以下代码重写了doTag()方法,方法中使用了getJspContext()方法来获取当前的JspContext对象,并将"Hello Custom Tag!"传递给JspWriter对象。
编译以上类,并将其复制到环境变量CLASSPATH目录中。最后创建如下标签库:<Tomcat安装目录>webapps\ROOT\WEB-INF\custom.tld。
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD</short-name>
<tag>
<name>Hello</name>
<tag-class>com.runoob.HelloTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
接下来,我们就可以在JSP文件中使用Hello标签:
<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello/>
</body>
</html>
以上程序输出结果为:
Hello Custom Tag!
2.2 访问标签体
你可以像标准标签库一样在标签中包含消息内容。如我们要在我们自定义的Hello中包含内容,格式如下:
<ex:Hello>
This is message body
</ex:Hello>
我们可以修改标签处理类文件,代码如下:
package com.runoob;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
StringWriter sw = new StringWriter();
public void doTag()
throws JspException, IOException
{
getJspBody().invoke(sw);
getJspContext().getOut().println(sw.toString());
}
}
接下来我们需要修改TLD文件,如下所示:
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD with Body</short-name>
<tag>
<name>Hello</name>
<tag-class>com.runoob.HelloTag</tag-class>
<body-content>scriptless</body-content>
</tag>
</taglib>
现在我们可以在JSP使用修改后的标签,如下所示:
<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello>
This is message body
</ex:Hello>
</body>
</html>
以上程序输出结果如下所示:
This is message body
2.3 自定义标签属性
你可以在自定义标准中设置各种属性,要接收属性,值自定义标签类必须实现setter方法, JavaBean 中的setter方法如下所示:
package com.runoob;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
private String message;
public void setMessage(String msg) {
this.message = msg;
}
StringWriter sw = new StringWriter();
public void doTag()
throws JspException, IOException
{
if (message != null) {
/* 从属性中使用消息 */
JspWriter out = getJspContext().getOut();
out.println( message );
}
else {
/* 从内容体中使用消息 */
getJspBody().invoke(sw);
getJspContext().getOut().println(sw.toString());
}
}
}
属性的名称是"message",所以setter方法是的setMessage()。现在让我们在TLD文件中使用的元素添加此属性:
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD with Body</short-name>
<tag>
<name>Hello</name>
<tag-class>com.runoob.HelloTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>message</name>
</attribute>
</tag>
</taglib>
现在我们就可以在JSP文件中使用message属性了,如下所示:
<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello message="This is custom tag" />
</body>
</html>
以上实例数据输出结果为:
This is custom tag
你还可以包含以下属性:
属性 | 描述 |
name | 定义属性的名称。每个标签的是属性名称必须是唯一的。 |
required | 指定属性是否是必须的或者可选的,如果设置为false为可选。 |
rtexprvalue | 声明在运行表达式时,标签属性是否有效。 |
type | 定义该属性的Java类类型 。默认指定为 String |
description | 描述信息 |
fragment | 如果声明了该属性,属性值将被视为一个 JspFragment。 |
以下是指定相关的属性实例:
.....
<attribute>
<name>attribute_name</name>
<required>false</required>
<type>java.util.Date</type>
<fragment>false</fragment>
</attribute>
.....
如果你使用了两个属性,修改TLD文件,如下所示:
.....
<attribute>
<name>attribute_name1</name>
<required>false</required>
<type>java.util.Boolean</type>
<fragment>false</fragment>
</attribute>
<attribute>
<name>attribute_name2</name>
<required>true</required>
<type>java.util.Date</type>
</attribute>
.....