前言: 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>
