天天看點

第七章_标簽檔案

下面是項目結構圖:

第七章_标簽檔案

下面是代碼清單:

這是firsttag.tag檔案

<%@ tag import="java.util.date" import="java.text.dateformat" %>  

<%  

    dateformat dateformat = dateformat.getdateinstance(dateformat.full) ;  

    date now = new date(system.currenttimemillis()) ;  

    out.println(dateformat.format(now)) ;  

%>  

firsttagtest.jsp

<%@ page language="java" import="java.util.*" pageencoding="utf-8"%>  

<%@ taglib prefix="easy" tagdir="/web-inf/tags" %>  

<html>  

  <head>  

    <title>my jsp 'firsttagtest.jsp' starting page</title>  

  </head>  

  <body>  

    today is <easy:firsttag></easy:firsttag>  

  </body>  

</html>  

項目運作截圖:

第七章_标簽檔案

像jsp頁面一樣,标簽檔案可以利用指令來控制jsp容器如何編譯和轉換标簽檔案。标簽檔案指令的文法與jsp指令的文法一樣:

<%@ directive (attribure=”value”)* %>

星号(*)表示括号中的内容可以不重複,也可以重複多次。這個文法可以用一種比較随意的方式進行改寫:

<%@ directive attribute1=”value1” attribute2=”value2” ... %>

其中的屬性必須用單引号或者雙引号括起來,起始符号<%@後面的空格和結束符号%>前面的空格是可選的,不過使用空格可以提升可讀性。

除了page之外,所有jsp指令在标簽檔案中都可以使用。這裡不用page,而是用tag指令。而且,在标簽檔案中,還有另外兩個指令可以使用:attribute和variable。下面是可以在标簽檔案中使用的所有指令。

1、tag。該指令與jsp頁面的page指令相似

2、include。用這個指令包含來自标簽檔案的其他資源

3、taglib。用這個指令從标簽檔案内部使用定制标簽類庫

4、attribute。用這個指令在标簽檔案中聲明一個屬性

5、variable用這個指令定義一個可以暴露給在調用jsp頁面的變量

tag指令的文法:

<%@ tag (attribute=”value”)* %>

以上文法用非正式的可以表示為:

<%@ tag attribute1=”value1” attribute2=”value2” ... %>

tag指令的屬性為:

display-name:通過xml工具顯示的簡稱,預設值為标簽檔案名,沒有tag擴充名。

body-content:關于這個标簽主體内容的資訊,它的值可以為empty、tagdependent或scriptless(預設)。

dynamic-attributes:表名對動态屬性的支援。它的值表示一個放置map的有界屬性,其中包含了這個調用期間傳遞的動态屬性名和值

small-icon:xml工具要用到的小圖檔檔案相對于context的路徑,或者相對于标簽資源檔案的路徑。我們通常不使用這個屬性。

large-icon:包含xml工具要用到的大圖示圖檔檔案相對于context的路徑,或者相對于标簽資源檔案的路徑。我們通常也不使用這個屬性。

description:描述該标簽的一個字元串。

example:該動作指令用法範例的一個非正式描述。

import:用于導入java類型,與page指令中的import屬性相同。

pageencoding:描述該标簽檔案的字元編碼,這個值的形式為“charset”,必須是字元編碼的iana名稱。該屬性與page指令的pageencoding屬性相同。

iselignored:表名忽略還是運算el表達式,該屬性的預設值為“false”,意為運算el表達式,該屬性與page指令的iselignored屬性相同。

除了import屬性之外,所有其他屬性在同一個标簽檔案的一個tag指令或者多個tag指令中都隻能出現一次。例如,以下tag檔案就是無效的,因為body-content屬性不止一次地出現在多個tag指令中:

<%@ tag display-name=”first tag file” body-content=”scriptless”%>

<%@ tag body-content=”empty” %>

下面是項目代碼片段:

includedemotag.tag

this tag file shows the use of whe include directive.  

the first include directive demontrates how you can include  

a static resource called included.html  

<br />  

here is the content of included.html  

<%@ include file="included.html" %>  

the second include directive includes another dynamic resource:  

included.tagf.  

<%@ include file="included.tagf"  %>  

included.html

<table>  

    <tr>  

        <td><b>menu</b></td>  

    </tr>  

        <td>cds</td>  

        <td>dvds</td>  

        <td>others</td>  

</table>  

included.tagf

    out.print("hello from included.tagf") ;  

includedemotagtest.jsp

<easy:includedemotag></easy:includedemotag>  

打開浏覽器輸入位址:

http://localhost:8089/testtag/includedemotagtest.jsp

第七章_标簽檔案

利用taglib指令可以使用标簽檔案中的定制标簽。taglib指令的文法如下:

<%@ taglib uri=”taglibraryuri prefix=”tagprefix””%>

uri屬性指定一個絕對或相對的uri,用來唯一辨別與這個字首相關的标簽類庫描述符,prefix屬性定義一個字元串,它将成為用于區分某個定制動作指令的字首。

有了taglib指令,就可以通過以下格式使用不帶内容主體的定制标簽:

<prefix:tagname/>

或者通過以下格式使用帶有内容主體的定制标簽:

<prefix:tagname>body</prefix:tagname>

attribute指令支援在标簽檔案中使用屬性,它相當于标簽類庫描述符中的attribute元素。文法如下:

<%@ attribute (attribute=”value”) %>

上述文法也可以用一種非正式的形式進行表達,如:

<%@ attribute attribute1 = “value1” attribute2=”value2” ... %>

attribute中的name屬性是必須的。屬性清單如下:

name:該标簽檔案能夠接受的屬性名稱,name屬性值必須在整個目前标簽檔案中都是唯一的。

required:表明該屬性是否是必須的,它的值可以是true或false。

fragment:表明該屬性是一個要通過标簽處理器進行運算的部分,或在傳給标簽處理器之前通過容器進行運算的一個普通屬性。它的值為true或者false。如果該屬性要通過标簽處理器進行運算,則值為true。

rtexprvalue:指定該屬性值是否可以在運作時通過一個scriplet表達式進行動态計算。這個值為true(預設值)或者false。

type:屬性值的類型,預設為java.lang.string

description:這個屬性的描述

下面是這個指令的測試:

encode.tag:

<%@ attribute name="input" required="true" %>  

<%!   

    private string encodehtmltag(string tag){  

        if(tag == null){  

            return null ;  

        }  

        int length = tag.length() ;  

        stringbuilder encodedtag = new stringbuilder(2 * length) ;  

        for(int i=0; i<length; i++){  

            char c = tag.charat(i) ;  

            if(c == '<'){  

                encodedtag.append("<") ;  

            }else if(c == '>'){  

                encodedtag.append(">") ;  

            }else if(c == '&'){  

                encodedtag.append("&") ;  

            }else if(c == '"'){  

                encodedtag.append(""") ;  

            }else if(c == ' '){  

                encodedtag.append(" ") ;  

            }else{  

                encodedtag.append(c) ;  

            }  

        return encodedtag.tostring() ;  

    }  

<%=encodehtmltag(input)%>  

encodetagtest.jsp

<%@ taglib prefix="easy"  tagdir="/web-inf/tags" %>  

    <title>my jsp 'encodetagtest.jsp' starting page</title>  

    <easy:encode input="<br />hello csdn" />  

第七章_标簽檔案

variable指令的文法如下:

<%@ variable (attribute=”value”)* %>

非正式形式的表達文法如下:

<%@ variable attribute1=”value” attribute2=”value2” %>

variable指令的屬性如下:

name-given:将要在調用jsp頁面的腳本語言或者el表達式中使用的變量名稱。如果使用name-form-attribute,就不能再用name-given屬性,反之亦然。name-given的值不能與該标簽檔案中的任何屬性值相同。

name-from-attribute:該屬性與name-given類似,但是它的值應該是一個屬性的名稱,并且它在開始進行标簽調用之時提供變量名稱,如果同時指定name-given和name-form-attribute屬性,或者這兩者都沒有指定,那麼将會産生編譯錯誤。

alias:這是一個局部範圍的屬性,用于存放該變量的值。

variable-class:該變量的類型,預設為java.lang.string

declare:表明是在調用頁面中聲明該變量,還是在調用之後在标簽檔案中聲明。預設值為true。

scope:所定義腳本變量的範圍,其可能值為at_begin、at_end和nested(預設)

description:該變量的描述

你可能會問,如果可以将處理結果直接輸出到在調用jsp頁面的jspwriter,那麼為什麼還需要variable指令呢?這是因為,隻将string發送到jspwriter,會導緻在調用的jsp頁面喪失如何使用該結果的靈活性。例如将伺服器的目前如期以long格式輸出。如果你還想以short格式提供伺服器的目前日期,那麼就必須另外編寫一個标簽檔案。有兩個标簽檔案來完成類似功能時,會增加不必要的維護問題。替代做法是,在标簽檔案中暴露兩個變量:longdate和shortdate。

下面是測試代碼:

vardemo.tag

<%@ variable name-given="longdate" %>  

<%@ variable name-given="shortdate" %>  

    dateformat longformat = dateformat.getdateinstance(dateformat.long) ;  

    dateformat shortformat = dateformat.getdateinstance(dateformat.short) ;  

    jspcontext.setattribute("longdate", longformat.format(now)) ;  

    jspcontext.setattribute("shortdate", shortformat.format(now)) ;  

<jsp:dobody></jsp:dobody>  

vardemotest.jsp

<%@ taglib tagdir="/web-inf/tags" prefix="easy" %>  

    <title>my jsp 'vardemotest.jsp' starting page</title>  

  today's date:  

    <easy:vardemo>  

        in long format: ${longdate}  

        <br />  

        in short format: ${shortdate}  

    </easy:vardemo>  

第七章_标簽檔案

标簽動作指令dobody隻能通過标簽檔案内部進行使用。我們可以用它調用标簽的主體。

dobody動作指令可以帶有屬性。如果需要将标簽調用的結果導入到某個變量中,就可以使用這些屬性。如果使用dobody時不帶屬性,那麼标準動作指令dobody就會将輸出結果寫入在所調用jsp頁面的jspwriter中。

标準指令dobody的屬性如下:

var:這是一個限域屬性名稱,用來儲存标簽主體調用的輸出。它的值儲存為java.lang.string。var和varreader二者不能同時存在。

varreader:這是一個限域屬性名稱,用來儲存标簽主體調用的輸出。它的值儲存為java.io.reader。var和varreader二者不能同時存在。

scope:結果變量的範圍。

下面是對于dobody的例子:

dobodydemo.tag

<jsp:dobody var="referer" scope="session"></jsp:dobody>  

main.jsp

<%@ taglib prefix="tags" tagdir="/web-inf/tags" %>  

your referer header:${header.referer}  

<br/>  

<tags:dobodydemo>  

    ${header.referer}  

</tags:dobodydemo>  

<a href="viewreferer.jsp">view</a> the referer as a session attribute.  

viewreferer.jsp

the referer header of the previous page is ${sessionscope.referer}  

searchenginer.html

please click <a href="main.jsp">here</a>  

第七章_标簽檔案
第七章_标簽檔案
第七章_标簽檔案

invoke标準動作指令與dobody相似,可以在标簽檔案中用來調用一個fragment屬性。前面說過,屬性可以帶有一個fragment屬性,它的值為true或false。如果fragment屬性值為true,那麼該屬性就是一個fragment屬性,你可以根據需要通過标簽檔案對它進行多次調用。invoke也可以帶有屬性。invoke的屬性如下,注意:隻有fragment屬性是必須的。

fragment:在這個标簽調用期間用于辨別該fragment的名稱。

var:這是一個限域屬性名稱,用來儲存标簽主體調用的輸出。它的值儲存為java.lang.string。var或varreader屬性二者不能同時存在。

下面是對于invoke的例子:

invokedemo.tag

<%@ attribute name="productdetails" fragment="true" %>  

<%@ variable name-given="productname" %>  

<%@ variable name-given="description" %>  

<%@ variable name-given="price" %>  

    jspcontext.setattribute("productname", "pelesonic dvd player") ;  

    jspcontext.setattribute("description", "dolby digital output through coaxial digital-audio jack,"+  

            " 500 lines horizontal resoulution-image digest viewing") ;  

    jspcontext.setattribute("price", "65") ;  

<jsp:invoke fragment="productdetails"></jsp:invoke>  

invoketest.jsp

    <title>my jsp 'invoketest.jsp' starting page</title>  

    <easy:invokedemo>  

        <jsp:attribute name="productdetails">  

            <table width="220" border="1">  

                <tr>  

                    <td><b>productname</b></td>  

                    <td><b>${productname}</b></td>  

                </tr>  

                    <td><b>description</b></td>  

                    <td><b>${description}</b></td>  

                    <td><b>price</b></td>  

                    <td><b>${price}</b></td>  

            </table>  

        </jsp:attribute>  

    </easy:invokedemo>  

下面是結果截圖:

第七章_标簽檔案