前言: TagLib可以使程序员自己开发JSP标签,并且可以重复利用。
Part 1 TagLib比JavaBean的优势是什么?
1. 方便处理网页内容的数据
2. 网页美工使用TagLib感觉更顺手
Part 2 如何制作和使用TagLib?
涉及4个方面:1.标记处理类 ;2.标记描述文件; 3.JSP 页面中用<% @ taglib %>引入标签; 4.在Web.xml中描述标签描述文件的位置(可选).
Part 3 标记处理类的API介绍
主要涉及javax.servlet.jsp.tagext和javax.servlet.jsp两个包。Jsp包中主要使用JspWriter 和PageContext类,相当与隐藏对象out和pageContext,不细介绍,下面关键介绍tagext包。
Tagext包中有两个接口Tag,BodyTag和9个类BodyContent,BodyTagSupport,TagAttributteInfo,TagData,TagExtraInfo,TagInfo,TagLibraryInfo,TagSupport,VariableInfo (粗体下划线的是最重要的四个类)
Part 4 BodyTagSupport和TagSupport的区别在哪里?
如果我们要获取标签中的内容,并对它进行处理时,比如对标签中间的字符< 替换为’<’等,必须继承自BodyTagSupport,否则继承TagSupport就足够了。
Part 5 TagSupport的API
最重要的两个方法是:
public int doStartTag() throws JspException
遇到起始标签进行的处理,有两个返回值,一个是Tag.SKIP_BODY,表示起止标签中间的内容被忽略,不做执行。另一个是Tag.EVAL_BODY_INCLUDE,表示标记中间的内容被正常执行。
public int doEndTag() throws JspException
遇到结束标签进行的处理,有两个返回值,一个是Tag.SKIP_PAGE, 表示执行立即结束,网页上剩余部分都被忽略。另一个是Tag.EVAL._PAGE表示JSP Page都能正常执行。
Part 6 如何处理标签的属性?
如果标签类似<prefix:myTag attr1=”123”> …</prefix:myTag>,处理类中必须写类似JavaBean的set和get方法。示例如下:
private int attr1;
public void setAttr1(int value)
{this.attr1=value;}
public int getAttr1()
{return this.attr1;}
注意:属性id,不用在标签处理类中实现get set代码,只需要在描述文件中指出id属性。
Part 7 BodyTagSupport的API
BodyTagSupport类继承TagSupport,有以下六个常用方法:
public int doStartTag() throws JspException
功能与TagSupport中一样,返回值有Tag.SKIP_BODY和Tag.
EVAL_BODY_BUFFERED
,Tag.SKIP_BODY表示标签中间的内容被忽略,Tag. EVAL_BODY_BUFFERED
表示标记中间的内容被执行,处理结果被放入BodyContent类中。
public int doEndTag() throws JspException
功能与返回值跟TagSupport中一样。
public void doInitBody() throws JspException
让用户能够新增初始值
public int doAfterBody() throws JspException
功能是让用户决定是否重新处理标记中间的内容,返回值有Tag.SKIP_BODY和BodyTag.EVAL_BODY_TAG,表示会重复不断地处理标记之间的内容。
public BodyContent getBodyContent()
获取标签的内容,以便于进行处理。
public void setBodyContent(BodyContent b)
设置标签内容。
Part 8 TagExtraInfo 和 VariableInfo
这两个类结合使用的目的是,在标签外部获取标签处理类中保存在页面的对象。该对象如果是JavaBean,则可以直接用<jsp:getProperty name=”id” property=”xxx”>取得该javabean的属性值,id是所保存的页面对象对应的变量名。标签外部包括:<prefix:mytag>开始到Page结束的范围,</prefix:mytag>开始到Page结束的范围,<prefix:mytag>和</prefix:mytag>中间的范围。
TagExtraInfo类最重要的一个方法是
public VariableInfo[] getVariableInfo(TagData data)
功能是返回所有的与此TagExtraInfo相关联的标签定义类里的变量信息。
VariableInfo类的构造函数
public VariableInfo(String ID,String ClassName,Boolean Declare, int Scope)
ID表示变量名称
ClassName表示类的名称
Declare表示之前是否申明过
Scope表示变量的使用范围:VariableInfo.AT_BEGIN表示从标签起始位置到Page结束,VariableInfo.AT_END表示标签结束位置到Page结束,VariableInfo.NESTED表示标签起止中间的范围。
Part 9 标记描述文件
标记描述文件是XML格式的文件,分三层来介绍:
第一层<taglib>是根元素,包括下列子元素
<tlibversion>
Tag Library的版本
<jspversion>
jsp的版本
<shortname>
定义Tag Library taglib命令中默认的Prefix值
<uri>
说明Tag Libray的文件来源,通常是空的
<info>
用来描述此TagLib的相关信息
<tag>表示用户子定以的标记,作为第二层详细介绍
第二层 <tag>描述文件的关键部分,包括下列子元素
<name>
用户定义的Tag名称
<tagclass>
标签的处理类全名称
<teiclass>
TagExtraInfo类的全名称
<bodycontent>
三种值:empty,JSP,tagdependent。empty表示没有body,JSP表示body中可以加入JSP程序代码,tagdependent表示内容交给tag自己处理
<info>
说明此tag的相关内容
<attribute>标签的属性,作为第三层介绍
第三层 <attribute>有3个子元素
<name>
属性的名称
<required>
属性必须存在? true为是,false是否,默认是false。
<rtexprvalue>
属性值是否可以为表达式,true为是,false为否。例如:是否可以这样使用?
<prefix:mytag num=”<%=request.getParameter(\” num\”)%>”/>
Part 10 如何在页面使用TagLib?
在页面先引入tag,然后就可以使用。其中uri指明taglib描述文件的路径,prefix表示标签的前缀。
<%@ taglib uri=”/WEB-INF/MyTagLib.tld” prefix=”mytag”%>
<h1><mytag:Hello/></h1>
Part 11 在Web.xml中设定taglib的uri假名。
<taglib>
<taglib-uri>
Taglib
</taglib-uri>
<taglib-location>
/WEB-INF/MyTaglib.tld
</taglib-location>
</taglib>
使用方式:
<%@ taglib uri=”Taglib” prefix=”myTag”%>
好处是,每次引入taglib时不用写长路径名称,并且改变了taglib描述的位置,只需要修改一个地方。
Part 12 一个TEI的示例:
//Hello tag处理类
package com.taglib;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import com.bean.*;
public class Hello
extends BodyTagSupport {
public Hello() {
}
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.println("Hello World Use Tag Library");
pageContext.setAttribute("Message", "TEI Message");
MyBean bean = new MyBean();
bean.setName("Wang Ming");
pageContext.setAttribute(getId(), bean);
}
catch (Exception e) {
System.out.println("Hello tag Error:" + e);
}
return Tag.EVAL_BODY_INCLUDE;
}
}
//TEI TEI类
package com.taglib;
import javax.servlet.jsp.tagext.*;
public class TEI extends TagExtraInfo{
public TEI() {
}
public VariableInfo[] getVariableInfo(TagData data)
{
return new VariableInfo[]{
new VariableInfo(data.getId(),"com.bean.MyBean",true,VariableInfo.AT_END),
new VariableInfo("Message","String",true,VariableInfo.AT_BEGIN)
};
}
}
//bean 类
package com.bean;
public class MyBean {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public MyBean() {}
}
<!--描述文件-->
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>MyTag</shortname>
<uri></uri>
<info>My Taglib</info>
<tag>
<name>Hello</name>
<tagclass>com.taglib.Hello</tagclass>
<teiclass>com.taglib.TEI</teiclass>
<bodycontent>JSP</bodycontent>
<attribute>
<name>id</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
<!--JSP文件-->
<%@ page contentType="text/html; charset=GBK" %>
<%@ taglib uri="/WEB-INF/mytaglib.tld" prefix="mytag" %>
<html>
<head>
<title>
TEI
</title>
</head>
<body bgcolor="#ffffff">
<h1>
<mytag:Hello id="Hello">
Ming <%=Message%>
</mytag:Hello>
</h1>
<jsp:getProperty name="Hello" property="name"/><br />
<%=Message%>
</h1>
</body>