定义:自定义标签是一种非常优秀的组件技术。通过使用自定义标签库,可以在简单的标签中封装复杂的
功能;
理解:其将JSP页面中的(复杂、重复并且格式统一的)内容封装,使用一个标签代替;
标签对应一个类,在类中有固定的方法,这些方法在编译JSP页面中的自定义标签时,被调用。方法内输出被封装的内容;
标签——>JAVA类——>类方法输出页面内容
自定义标签的分类:
1.简单标签;
2.带属性的标签;
3.带标签体的标签;
4.可以被script使用的标签;
实现自定义标签的步骤
1.开发自定义标签处理类;
2.建立一个*.tld文件,每个*.tld文件对应一个标签库,每个标签库对应多个标签;
3.在web.xml文件中增加自定义标签的定义;
4.在JSP文件中使用自定义标签;
一;开发自定义标签类
类名 | 方法名 | 作用 | 备用 |
TagSupport | doEndTag() destroy() | 该方法在标签结束生成页面内容 销毁标签时调用的方法 | 简单标签 带属性的标签 |
BodyTagSupport | doStartTag() doAfterBody() doEndTag()
| 开始处理方法时,调用该方法 每次标签体处理完后调用该方法 标签体结束时调用该方法 | 带标签体的标签 |
2.2 标签流向控制
返回值 | 意义 |
SKIP_BODY | 表示不用处理标签体,直接调用doEndTag()方法。 |
SKIP_PAGE | 忽略标签后面的JSP内容。 |
EVAL_PAGE | 处理标签后,继续处理JSP后面的内容。 |
EVAL_BODY_BUFFERED | 表示需要处理标签体。 |
EVAL_BODY_INCLUDE | 表示需要处理标签体,但绕过setBodyContent()和doInitBody()方法 |
EVAL_BODY_AGAIN | 对标签体循环处理。 |
二;建立TLD文件
TLD是Tag Library Definition的缩写,即标签库定义,文件的后缀是.tld,每个TLD文件对应一个标签库,一个标签库对应多个标签;
<taglib>
定义标签库版本
<tlib-version>1.0</tlib-version>
定义JSP版本
<jsp-version>1.2</jsp-version>
配置第一个标签
<short-name>mytag</short-name>
<tag>
配置标签名
<name>helloworld</name>
确定标签的处理类
<tag-class>mytag.HelloWorldTag</tag-class>
确定标签体,标签体为空
<body-content>empty</body-content>
</tag>
</taglib>
三;在web.xml文件中增加标签库定义
<jsp-config>
定义标签库
<taglib>
确定标签库的URL
<taglib-uri>/helloworld</taglib-uri>
确定标签库定义文件的位置
<taglib-location>/WEB-INF/helloworld.tld</taglib-location>
</taglib>
</jsp-config>
四:使用标签库
1.导入标签库:使用taglib编译指令导入标签
<%@ taglib uri="/helloworld" prefix="mytag"%>
2.使用标签:在JSP页面中使用自定义标签
<mytag:helloworld></mytag:helloworld>
---------------------------------------------------------------------------------------
案例
案例目标
配置三种标签
1.简单
2.带属性
3.带标签体
一;标签类的实现
1.简单标签
package mytag;
import java.io.IOException;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* 简单标签实体类
*/
public class HelloWorldTag extends TagSupport {
/**
* 标签开始 执行语句
*/
@Override
public int doStartTag() throws JspException {
return EVAL_BODY_INCLUDE;
}
/**
* 标签结束 执行语句
*/
@Override
public int doEndTag() throws JspException {
try{
pageContext.getOut().write("Hello world");
}catch(Exception ex){
throw new JspTagException("错误");
}
return EVAL_PAGE;
}
}
2.带属性标签类
package mytag;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import entity.Peron;
/**
* 带属性的标签
*/
public class QueryTag extends TagSupport {
// 标签的属性
private int rows;
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
/**
* 标签处理
*/
@Override
public int doEndTag() throws JspException {
try {
// 生成假数据对象
Peron p1 = new Peron("no1", 10), p2 = new Peron("no2", 13), p3 = new Peron(
"no3", 15);
// 生成假集合
List<Peron> PL = Arrays.asList(p1, p2, p3);
// 获取页面输出流
Writer out = pageContext.getOut();
// 输出
out.write("<table>");
Peron p = null;
for (int i = 0;i < rows;i++) {
p = PL.get(i);
out.write("<tr>");
out.write("<td>");
out.write(p.getName());
out.write("</td>");
out.write("<td>");
out.write(p.getAge());
out.write("</td>");
out.write("</tr>");
}
out.write("</table>");
} catch (Exception ex) {
System.out.println("标签处理产生异常");
}
return EVAL_PAGE;
}
}
3.带标签体的标签
1.外部标签类
package mytag;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
* 带标签体的标签
* 完成迭代功能
*/
public class MyiteratorTag extends BodyTagSupport{
//标签需要迭代的集合对象名
//从页面内传递一个值,该值代表页面page内的一个集合的名称
private String bean;
//集合对象的元素下标值
private String item;
//集合当前索引
private int i = 0;
//集合大小
private int size ;
//?
private List<String> itemList;
public String getBean() {
return bean;
}
public void setBean(String bean) {
this.bean = bean;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
/**
* 开始处理标签时,调用该方法
*/
@Override
public int doStartTag() throws JspException {
try{
pageContext.getOut().write("进入MyiteratorTag-doStartTag方法");
}catch(Exception ex){}
//从page范围中获取List对象
itemList = (List<String>)pageContext.getAttribute(bean);
//获取集合长度
size = itemList.size();
//将集合当前索引的值放在page范围的item变量中
pageContext.setAttribute(item, itemList.get(i));
//返回值为EVAL_BODY_BUFFERED;表明需要计算标签体
return EVAL_BODY_BUFFERED;
}
/**
* 每次标签体处理完后调用该方法
*
*/
@Override
public int doAfterBody() throws JspException {
try{
pageContext.getOut().write("进入MyiteratorTag-doAfterbody方法");
}catch(Exception ex){}
//移动List对象的索引位置
i++;
//如果索引已经超过集合的长度
if(i>=size){
//索引归零
i=0;
//不在计算标签体
return SKIP_BODY;
}
//将集合的当前元素值放入page范围的item属性中
pageContext.setAttribute(item, itemList.get(i));
//循环计算标签体
return EVAL_BODY_AGAIN;
}
/**
* 标签体结束时调用该方法
*/
@Override
public int doEndTag() throws JspException {
try{
pageContext.getOut().write("进入MyiteratorTag-doEndTag方法");
//输出标签体内容
bodyContent.writeOut(pageContext.getOut());
}catch(Exception ex){
throw new JspException("错误");
}
return super.doEndTag();
}
}
2.内部标签类
package mytag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
/**
* 嵌套的内部标签
*/
public class WritorTag extends TagSupport {
//item属性 该标签从page中查找item的属性,并输出属性值
private String item;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
/**
* 开始处理标签时的调用方法
*/
@Override
public int doStartTag() throws JspException {
try{
pageContext.getOut().write((String)pageContext.getAttribute("item"));
}catch(Exception ex){
throw new JspException("错误");
}
return super.doStartTag();
}
}
二。标签体的TLD文件配置
1.简单标签
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<!-- 定义标签库版本 -->
<tlib-version>1.0</tlib-version>
<!-- 定义JSP版本 -->
<jsp-version>1.2</jsp-version>
<!-- 定义标签库名称 -->
<short-name>mytag</short-name>
<!-- 定义第一个标签 -->
<tag>
<!-- 配置标签名 -->
<name>helloworld</name>
<!-- 确定实现标签的标签类 -->
<tag-class>mytag.HelloWorldTag</tag-class>
<!-- 确定标签的标签体,标签体为空 -->
<body-content>empty</body-content>
</tag>
</taglib>
2.带属性的标签
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<!-- 定义标签库版本 -->
<tlib-version>1.0</tlib-version>
<!-- 定义JSP版本 -->
<jsp-version>1.2</jsp-version>
<short-name>querytag</short-name>
<!-- 配置标签 -->
<tag>
<!-- 配置标签名称 -->
<name>query</name>
<!-- 配置标签实现类 -->
<tag-class>mytag.QueryTag</tag-class>
<!-- 指定标签体为空 -->
<body-content>empty</body-content>
<!-- 配置属性 -->
<attribute>
<name>rows</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
3.带标签体的标签
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>iterator</short-name>
<!-- 配置迭代器标签 -->
<!-- 外部标签 -->
<tag>
<!-- 配置标签名 -->
<name>iterator</name>
<!-- 配置标签的实现类 -->
<tag-class>mytag.MyiteratorTag</tag-class>
<!-- 配置标签体 -->
<body-content>JSP</body-content>
<!-- 配置标签属性 -->
<attribute>
<name>bean</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>item</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 配置输出标签 -->
<!-- 内部标签 -->
<tag>
<!-- 配置标签名 -->
<name>write</name>
<!-- 配置标签的实现类 -->
<tag-class>mytag.WritorTag</tag-class>
<!-- 配置标签内容 -->
<body-content>empty</body-content>
<!-- 配置标签属性 -->
<attribute>
<name>item</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
三。WEB.XML文件配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<jsp-config>
<taglib>
<!-- 配置标签的引用地址 JSP页面中引用时使用-->
<taglib-uri>/helloworld</taglib-uri>
<!-- 配置标签的TLD文件地址 -->
<taglib-location>/WEB-INF/helloworld.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/query</taglib-uri>
<taglib-location>/WEB-INF/query.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/iterator</taglib-uri>
<taglib-location>/WEB-INF/iterator.tld</taglib-location>
</taglib>
</jsp-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
四:JSP调用
<%@ page language="java" contentType="text/html; charset=GBK"
pageEncoding="GBK" import="java.util.*"%>
<%@ taglib uri="/helloworld" prefix="mytag"%>
<%@ taglib uri="/query" prefix="query"%>
<%@ taglib uri="/iterator" prefix="iter"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<mytag:helloworld></mytag:helloworld>
<query:query rows="3" />
<%
//创建输出对象
List<String> a = new ArrayList<String>();
a.add("a");
a.add("b");
a.add("c");
//将a放入 page 范围内
pageContext.setAttribute("a", a);
%>
<table>
<iter:iterator bean="a" item="item">
<tr>
<td>
<iter:write item="item"/>
</td>
</tr>
</iter:iterator>
</table>
</body>
</html>