1. 程式人生 > >JSP規範_Tag Library標簽庫

JSP規範_Tag Library標簽庫

組成 目錄 system 部分 使用 package open pat image

  • 什麽是標簽庫

  標簽庫是jsp頁面要使用的標簽元素的集合,前面筆記總結的都是默認的標簽,容器提供了另外幾套標準標簽庫和用戶自定以標簽庫來零化jsp頁面中java代碼,我將不筆記標準標簽  庫的各個細則,只約略記錄一下sun公司提供的幾個標簽有:c/fmc/sql/x/fn幾個前綴標識,它封裝了程序員常用的一些標簽,我個人是不提倡用這些標簽因為難以記憶,如果有公司  采用這樣的技術手段,只需要查規範即可,標簽本質上只是java代碼的標簽化而已。然後如果有公司使用自定義標簽庫,則只需要知道標簽庫如何自定義和使用即可。下面的內容  將圍繞自定義標簽展開。

一個標簽的組成

  標簽概念的完全組成部分是空標簽、標簽屬性和標簽體。自定義的標簽實際上就是實現了傳統標簽和簡單標簽接口的java類,然後完成標簽類的部署工作後,程序員就可以在jsp中  使用。

  1. 標簽接口在容器中的生命周期:

  javax.servlet.jsp.tagext.Tag接口作為頂級接口定義了標簽需要實現的基本方法,其相關類的靜態層次這裏忽視,只約略筆記相關的幾個周期方法:

  1.1容器在創建標簽處理器的實例後(需要部署告知容器),調用setPageContext()方法設置標簽的頁面上下文,然後調用setParent()設置此標簽的父標簽,沒有則為null;

  1.2調用標簽處理器的setXXX(),設置標簽的屬性,如果jsp中的標簽定義屬性則沒有這一步驟;

  1.3調用doStartTag()方法,如果返回EVAL_BODY_INCLUDE常量(接口中定義的),則將標簽體輸出到當前的輸出流中;如果返回SKIP_BODY則忽略標簽體。

  1.4調用doEndTag()方法,返回PAGE,則執行jsp頁面之余,返回SKIP_BODY則忽略頁面之余;和上一步驟類似,該步驟中的代碼會原樣編寫進jsp對應的servlet代碼中。

  1.5容器緩存該實例,重復使用;

  1.6需要釋放該實例時,調用release();

  知道了其生命周期後,我們就可以實現簡單標簽或傳統標簽接口,在對應的方法中寫入合適的處理內容。

  2.標簽實現類的部署

  完成標簽處理器的編寫後,需要告知容器該處理器的信息,讓容器擁有對處理器的管理權。

  2.1標簽庫描述符(Tag Library Descriptor,TLD)

  編寫.tld文件到META-INF或WEB-INF目錄下(最好創建自目錄tags),下面貼上一個案例:

  代碼結構

  技術分享圖片

  編寫便簽處理器HelloTag.java

技術分享圖片
package tags;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;

//實現傳統標簽接口
public class HelloTag implements Tag{
    private PageContext pageContext;
    private Tag parent;
    //設置context對象
    public void setPageContext(PageContext pc) {
        this.pageContext=pc;
    }
    //如果標簽嵌套,設置父標簽
    public void setParent(Tag t) {
        this.parent=t;
    }
    //獲取父標簽
    public Tag getParent() {
        return parent;
    }
    //當處理標簽時,該方法被調用
    public int doStartTag() throws JspException {
        return SKIP_BODY;//有效返回值0,跳過body評估,即忽略標簽體
    }
    //當處理結束時,該方法被調用
    public int doEndTag() throws JspException {
        JspWriter out = pageContext.getOut(); 
        try {
            out.println("歡迎來到我的個人網站!");
        }catch(IOException e) {
            System.out.println(e.toString());
        }
        return EVAL_PAGE;//返回6,繼續評估該page,即jsp頁面的余下部分繼續執行
    }
    @Override
    public void release() {}//釋放標簽處理器資源
    
}
View Code

  標簽描述文件MyTaglib.tld

技術分享圖片
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
    version="2.1"> 
    <tlib-version>1.0</tlib-version>
    <short-name>my</short-name><!-- 為標簽庫定義一個簡短名字,jsp頁面編輯使用 ,作為首先前綴值使用-->
    <display-name>My Tag</display-name><!-- 為標簽庫指定一個簡短名字,被一些工具所顯示 -->
    <discription>Custom Tag library</discription>
    <tag><!-- 沒有屬性沒有標簽體的標簽 -->
        <name>hello</name>
        <tag-class>tags.HelloTag</tag-class>
        <body-content>empty</body-content>
    </tag>
    
    <tag><!-- 帶屬性 的標簽 -->
        <name>max</name>
        <tag-class>tags.MaxTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>num1</name>
            <required>true</required><!-- 設置標簽屬性為必填 -->
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>num2</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
    <tag><!-- 帶標簽體的標簽 -->
        <name>greet</name>
        <tag-class>tags.GreetTag</tag-class>
        <body-content>JSP</body-content><!-- 代表標簽體可以包含jsp代碼 -->
    </tag>
    
    <!-- 
    <description/> 為標簽庫提供一個文本描述 
    <smaill-icon/> 為標簽庫提供小圖標 
    <large-icon/> 為標簽庫提供大圖標 
    <validator> 標簽庫的驗證器 
        <description></description> 為驗證器提供一個文本描述 
        <validator-class></validator-class> 指定驗證的實現類 
        <init-param></init-param> 驗證類的初始化參數
    </validator>
    <listener> 標簽庫的監聽器 
        <description/> 監聽器提供一個文本描述 
        <dispalay-name/> 簡短名字 
        <icon> 指定圖標 
        <small-icon/> 指定小圖標
        <large-scon/> 大圖標
        </icon>
        <listener-class/> 指定監聽器類完全限定名 
    </listener>
    <tag>指定標簽的配置信息 
        <description/> 為標簽庫提供一個文本描述 
        <display-name></display-name> 為標簽指定一個簡短名字 
        <icon>
            <small-icon/><large-icon/>
        </icon>
        <name></name> 指定自定義標簽的名字 
        <tag-class/> 指定標簽的實現類 
        <tei-class/> 為容器在轉換階段提供該標簽的附加信息
        <body-content/> 指定標簽體的格式 
    </tag>
    <tag-file> 關於該標簽文件的信息 
        <description/> 標簽文件提供一個文本描述 
        <display-name/> 為標簽文件提供一個簡短名 
        <icon/> 為標簽文件指定大小圖標,省略子標簽 
        <name/> 指定標簽文件的名字 
        <path/> 指定標簽文件的路徑
        <example/> 提供一個使用例子描述 
        <tag-extension/> 提供標簽的擴展信息 
    </tag-file>
    <function> 與EL表達式有關 
        <description/> 為EL函數指定一個簡短名字 
        <icon/> 指定一個圖標 ,子標簽省略
        <name/> 給函數指定一個名字 
        <function-class/> 實現el函數的類完全限定 
        <function-signture/> 指定EL函數的原型 
        <example/> 提供一個使用案例 
        <function-extension/> 提供額外信息 
    </function>
     -->
</taglib>
View Code

  可以看到,文件中每一個tag標簽就是對一個實現Tag接口的處理器的描述,標簽的name屬性,作為jsp中指示要使用的標簽的標識,jap中使用標簽庫+標簽名的方式來定位要使  用的標簽。標簽庫會在web.xml中進行說明。

  標簽庫在容器中的部署web.xml

技術分享圖片
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">

<!-- 標簽即動作!! -->
<!-- 對自定義標簽的部署,即容器啟動時就根據部署文件找到tld,再根據tld找到對應的標簽實現類,再jsp的解析過程中遇到標簽就替換成對應的實現類代碼 -->
<jsp-config><!-- 為jsp提供全局配置信息 -->
    <taglib><!-- 為頁面的tag提供部署 -->
        <taglib-uri>/mytag</taglib-uri><!-- 對應jsp中的uri標識 -->
        <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>
    </taglib>
</jsp-config>
</web-app>
View Code

  該文件中主要告知容器標簽庫的描述文件,讓容器啟動時根據描述文件加載標簽處理器。

  自定義標簽的使用hello.jsp

技術分享圖片
<%@ page language="java" contentType="text/html; charset=gb2312"%>
<%@ taglib uri="/mytag" prefix="my" %><!-- 指定標簽庫及其簡短表示,根據uri去部署描述文件中尋找對應的標簽描述文件即可找到對應的標簽類 -->
<html>
<head>
    <title><my:hello/></title><!-- 說明使用標簽庫中的某個標簽 -->
</head>
<body>
    <my:hello/>
</body>
</html>
View Code

  總結:盡管個人不是很提供使用標簽,但是不排除有技術成熟的公司在使用,如果項目中遇到,則以上的案例作為基本的操作指南:在jsp中使用taglib指令說明要使用的標簽所在的標簽庫,即web.xml中對應標簽庫描述文件的uri標識;找到標簽文件所在位置打開,查找標簽庫的short name作為jsp中taglib指令的prefix,即可在使用某個標簽時使用前綴+標簽名的方式定位要使用的標簽;在標簽文件中找到要使用的tag標簽name,就可以標簽庫前綴+標簽名使用了。標準標簽庫可以理解為sun公司給寫好的自定義標簽,文章開始已經談到就不再贅述,如果要使用就可以直接再jsp中使用taglib指令和前綴+標簽的方式使用即可。EL表達式可以理解為對javabean的直接訪問,也不作為重點學習目標,因為他們本質上只是簡化jsp中的java代碼而已,如果用到可以查閱規範!

  

JSP規範_Tag Library標簽庫