Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲免费视频网站,久久一区二区三区四区,91精品国产综合成人

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JSP 自定義標簽

          自定義標簽是用戶定義的JSP語言元素。當JSP頁面包含一個自定義標簽時將被轉化為servlet,標簽轉化為對被 稱為tag handler的對象的操作,即當servlet執行時Web container調用那些操作。

          JSP標簽擴展可以讓你創建新的標簽并且可以直接插入到一個JSP頁面。 JSP 2.0規范中引入Simple Tag Handlers來編寫這些自定義標記。

          你可以繼承SimpleTagSupport類并重寫的doTag()方法來開發一個最簡單的自定義標簽。

          創建"Hello"標簽

          接下來,我們想創建一個自定義標簽叫作<ex:Hello>,標簽格式為:

          <ex:Hello />

          要創建自定義的JSP標簽,你首先必須創建處理標簽的Java類。所以,讓我們創建一個HelloTag類,如下所示:

          package com.runoob;

          import javax.servlet.jsp.tagext.*;

          import javax.servlet.jsp.*;

          import java.io.*;

          public class HelloTag extends SimpleTagSupport {

          public void doTag() throws JspException, IOException {

          JspWriter out = getJspContext().getOut();

          out.println("Hello Custom Tag!");

          }

          }

          以下代碼重寫了doTag()方法,方法中使用了getJspContext()方法來獲取當前的JspContext對象,并將"Hello Custom Tag!"傳遞給JspWriter對象。

          編譯以上類,并將其復制到環境變量CLASSPATH目錄中。最后創建如下標簽庫:<Tomcat安裝目錄>webapps\ROOT\WEB-INF\custom.tld。

          <taglib>

          <tlib-version>1.0</tlib-version>

          <jsp-version>2.0</jsp-version>

          <short-name>Example TLD</short-name>

          <tag>

          <name>Hello</name>

          <tag-class>com.runoob.HelloTag</tag-class>

          <body-content>empty</body-content>

          </tag>

          </taglib>

          接下來,我們就可以在JSP文件中使用Hello標簽:

          <%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>

          <html>

          <head>

          <title>A sample custom tag</title>

          </head>

          <body>

          <ex:Hello/>

          </body>

          </html>

          以上程序輸出結果為:

          Hello Custom Tag!

          訪問標簽體

          你可以像標準標簽庫一樣在標簽中包含消息內容。如我們要在我們自定義的Hello中包含內容,格式如下:

          <ex:Hello>

          This is message body

          </ex:Hello>

          我們可以修改標簽處理類文件,代碼如下:

          package com.runoob;

          import javax.servlet.jsp.tagext.*;

          import javax.servlet.jsp.*;

          import java.io.*;

          public class HelloTag extends SimpleTagSupport {

          StringWriter sw = new StringWriter();

          public void doTag()

          throws JspException, IOException

          {

          getJspBody().invoke(sw);

          getJspContext().getOut().println(sw.toString());

          }

          }

          接下來我們需要修改TLD文件,如下所示:

          <taglib>

          <tlib-version>1.0</tlib-version>

          <jsp-version>2.0</jsp-version>

          <short-name>Example TLD with Body</short-name>

          <tag>

          <name>Hello</name>

          <tag-class>com.runoob.HelloTag</tag-class>

          <body-content>scriptless</body-content>

          </tag>

          </taglib>

          現在我們可以在JSP使用修改后的標簽,如下所示:

          <%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>

          <html>

          <head>

          <title>A sample custom tag</title>

          </head>

          <body>

          <ex:Hello>

          This is message body

          </ex:Hello>

          </body>

          </html>

          以上程序輸出結果如下所示:

          This is message body

          自定義標簽屬性

          你可以在自定義標準中設置各種屬性,要接收屬性,值自定義標簽類必須實現setter方法, JavaBean 中的setter方法如下所示:

          package com.runoob;

          import javax.servlet.jsp.tagext.*;

          import javax.servlet.jsp.*;

          import java.io.*;

          public class HelloTag extends SimpleTagSupport {

          private String message;

          public void setMessage(String msg) {

          this.message = msg;

          }

          StringWriter sw = new StringWriter();

          public void doTag()

          throws JspException, IOException

          {

          if (message != null) {

          /* 從屬性中使用消息 */

          JspWriter out = getJspContext().getOut();

          out.println( message );

          }

          else {

          /* 從內容體中使用消息 */

          getJspBody().invoke(sw);

          getJspContext().getOut().println(sw.toString());

          }

          }

          }

          屬性的名稱是"message",所以setter方法是的setMessage()。現在讓我們在TLD文件中使用的<attribute>元素添加此屬性:

          <taglib>

          <tlib-version>1.0</tlib-version>

          <jsp-version>2.0</jsp-version>

          <short-name>Example TLD with Body</short-name>

          <tag>

          <name>Hello</name>

          <tag-class>com.runoob.HelloTag</tag-class>

          <body-content>scriptless</body-content>

          <attribute>

          <name>message</name>

          </attribute>

          </tag>

          </taglib>

          現在我們就可以在JSP文件中使用message屬性了,如下所示:

          <%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>

          <html>

          <head>

          <title>A sample custom tag</title>

          </head>

          <body>

          <ex:Hello message="This is custom tag" />

          </body>

          </html>

          以上實例數據輸出結果為:

          This is custom tag

          你還可以包含以下屬性:

          屬性描述
          name定義屬性的名稱。每個標簽的是屬性名稱必須是唯一的。
          required指定屬性是否是必須的或者可選的,如果設置為false為可選。
          rtexprvalue聲明在運行表達式時,標簽屬性是否有效。
          type定義該屬性的Java類類型 。默認指定為 String
          description描述信息
          fragment如果聲明了該屬性,屬性值將被視為一個 JspFragment

          以下是指定相關的屬性實例:

          .....

          <attribute>

          <name>attribute_name</name>

          <required>false</required>

          <type>java.util.Date</type>

          <fragment>false</fragment>

          </attribute>

          .....

          如果你使用了兩個屬性,修改TLD文件,如下所示:

          .....

          <attribute>

          <name>attribute_name1</name>

          <required>false</required>

          <type>java.util.Boolean</type>

          <fragment>false</fragment>

          </attribute>

          <attribute>

          <name>attribute_name2</name>

          <required>true</required>

          <type>java.util.Date</type>

          </attribute>

          .....

          如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!

          然JSTL提供了很多豐富的標簽,但是在某些情況下,這些標簽還是不能夠滿足我們的業務需求,所以sun公司也提供了自定義標簽的功能,可以根據實際業務需求創建相應的標簽。自定義標簽在一些很老的項目中會經常見到,因為那個時候基本上是基于Servlet和JSP進行項目的開發,為了應對自身的項目需求,每個公司都會自己創建自己的標簽庫,從而簡化開發,提高開發效率。

          自定義JSTL標簽只需要下面幾個步驟即可:

          1. 第一步:創建一個類,繼承自SimpleTagSupport類。
          2. 第二步:重寫doTag()方法,在這個方法中實現自定義標簽的處理邏輯。
          3. 第三步:在WEB-INF目錄下面,創建對應標簽的tld描述文件。
          4. 第四步:在JSP頁面中,通過<%@taglib%>指令自定義標簽即可。

          1.1、繼承SimpleTagSupport

          創建一個CustomTag類,繼承自SimpleTagSupport類,重寫doTag()方法。

          package com.gitcode.tag;
          
          import javax.servlet.jsp.JspException;
          import javax.servlet.jsp.JspWriter;
          import javax.servlet.jsp.tagext.JspFragment;
          import javax.servlet.jsp.tagext.SimpleTagSupport;
          import java.io.IOException;
          import java.io.StringWriter;
          
          /**
           * 自定義JSTL標簽
           */
          public class CustomTag extends SimpleTagSupport {
              /**
               * 自定義標簽屬性
               */
              private String content;
              /**
               * 標簽體內容
               */
              private StringWriter body = new StringWriter();
          
              public void setContent(String content) {
                  this.content = content;
              }
          
              @Override
              public void doTag() throws JspException, IOException {
                  // 1、獲取輸出流對象
                  JspWriter writer = this.getJspContext().getOut();
                  if (content == null) {
                      // 屬性等于空,則直接獲取標簽之間的body內容
                      JspFragment jspBody = this.getJspBody();
                      // 調用方法
                      jspBody.invoke(body);
                      // 輸出內容
                      writer.println(body.toString());
                  } else {
                      // 如果屬性名稱不為空,則輸出屬性名稱的內容
                      writer.println(content);
                  }
              }
          }

          1.2、創建tld描述文件

          在WEB-INF目錄下,我們創建一個tld目錄,用于保存我們自定義JSTL標簽的tld描述文件,tld描述文件中,需要編寫如下內容:

          <?xml version="1.0" encoding="UTF-8" ?>
          
          <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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
                  version="2.0">
          
              <tlib-version>1.1</tlib-version>
              <short-name>custom_tag</short-name>
          
              <tag>
                  <description>自定義JSTL標簽的描述內容</description>
                  <name>custom_tag</name>
                  <tag-class>com.gitcode.tag.CustomTag</tag-class>
                  <!-- 標簽之間的內容是腳本 -->
                  <body-content>scriptless</body-content>
                  <attribute>
                      <description>屬性的描述內容</description>
                      <name>content</name>
                      <required>false</required>
                      <rtexprvalue>true</rtexprvalue>
                  </attribute>
              </tag>
          </taglib>

          如下圖所示:

          1.3、使用自定義標簽

          新建一個custom.jsp頁面,使用<%@taglib%>指令引入自定義標簽,如下所示:

          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <%-- 引入標簽庫 --%>
          <%@ taglib prefix="custom_tag" uri="WEB-INF/tld/custom_tag.tld" %>
          <html>
          <head>
              <title>JSTL標簽庫之自定義標簽</title>
          </head>
          <body>
              <h3>JSTL標簽庫之自定義標簽</h3>
              <custom_tag:custom_tag content="content屬性內容"></custom_tag:custom_tag>
          
              <h3>JSTL標簽庫之自定義標簽</h3>
              <custom_tag:custom_tag>
                  <ul>
                      <li>第一行</li>
                      <li>第二行</li>
                      <li>第三行</li>
                  </ul>
              </custom_tag:custom_tag>
          </body>
          </html>

          運行結果如下所示:

          需要注意的是,prefix屬性值必須和custom_tag.tld描述文件中的<short-name>標簽值保持一致,否則無法引用自定義標簽

          以上,就是JSTL自定義標簽的使用,創建自定義標簽可以將公用的代碼封裝起來,后續要使用的時候,可以減少代碼的開發,從而提高開發效率。

          今天就到這里,未完待續~~

          實現自定義標簽時,有時需要對標簽體的內容進行處理以后再向瀏覽器輸出,比如將小寫英文字母轉化為大寫,將HTML標簽進行轉義等。為了實現這樣的功能,JSP規范中它義了一個BodyTag接口,它繼承自IterationTag接口,并在IterationTag接口基礎上新增了兩個方法和一個靜態常量,具體如下。

          1. EVAL_BODY_BUFFERED常量

          如果標簽處理器類實現了BodyTag接口,它的doStartTag()方法除了可以返回SKIP_BODY和EVAL_BODY_INCLUDE常量之外,還可以返回EVAL_BODY_BUFFERED常量。當doStartTag()方法返回EVAL_BODY_BUFFERED常量時,JSP容器將會創建個javax.servlet.jsp.tagext.BodyContent對象,使用該對象來執行標簽體。關于BodyContent類的用法,將在下面進行詳細的講解。

          2. setBodyContent(BodyContent b)方法

          當且僅當doStartTag()方法返回EVAL_BODY_BUFFERED常量時,JSP容器才會調用setBodyContent()方法,通過該方法將BodyContent對象傳遞給標簽處理器類使用。

          3. dolnitBody()方法

          JSP容器在調用setBodyContent()方法后會調用doInitBody()方法來完成些初始化工作,該方法的調用在標簽體執行之前。

          其中,最重要的是setBodyContent()方法。為了幫助大家更好地理解BodyTag接口處理標簽內容的方式,有必要對BodyContent類進行詳細講解。

          BodyContent類是JspWriter類的子類,它在JspWriter的基礎上增加了一個用于存儲數據的緩沖區(確切地說緩沖區是在BodyContent的子類org.apache.jasper.runtime.BodyContentImple中定義的),當調用BodyContent對象的方法寫數據時,數據將被寫人到BodyContent內部的緩沖區中。

          明白了BodyContent類的這個特點,就不難理解JSP容器是如何利用BodyContent對象來處理標簽體內容了。當標簽處理器類的doStartTag()方法返回EVAL_BODY_BUFFERED常量時,JSP容器會創建一個BodyContent對象,然后調用該對象的write()方法將標簽體的內容寫人BodyContent對象的緩沖區中,開發者只要能夠訪問BodyContent緩沖區的內容,就能對標簽體的內容進行處理。在BodyContent類中定義了一些用于訪問緩沖區內容的方法,具體如下表所示。

          BodyContent類的常用方法

          方法聲明

          功能描述

          String getString()

          以字符串的形式返回BodyContent對象緩沖區中保存的數據

          Reader getReader()

          返回一個關聯BodyContent對象緩沖區中數據的Reader對
          象,通過Reader對象可以讀取緩沖區中的數據

          void clearBody()

          用于清空BodyContent對象緩沖區中的內容

          JspWriter getEnclosingWriter()

          用于返回BodyContent對象中關聯的JspWriter對象。當JSP容器創建BodyContent對象后,PageContext對象中的"out"屬性不再指向JSP的隱式對象,而是指向新創建的BodyContent對象。同時,在BodyContent對象中會用一個JspWriter類型的成員變量enclosingWriter記住原來的隱式對象,getEnclosingWriter()方 法返回的就是原始的JSP隱式對象

          writerOut(Writer out)

          用于將BodyContent對象中的內容寫人到指定的輸出流

          在上表列舉的所有方法中,其中getEnclosingWriter()方法最難理解,但是,只需要記住該方法的返回值為out即可。

          除了BodyContent類外,在BodyTag接口還會涉及很多常量和方法,為了讓大家更好地掌握標簽處理器的執行流程,接下來通過一張圖來描述,具體如下圖所示。

          標簽處理器的執行流程

          上圖中清楚地描述了JSP容器執行標簽處理器的過程。其中,release()方法之所以使用用虛線,是因為這個方法不會在標簽處理器每次執行都被JSP容器調用,只有當標簽處理器對象作為垃圾被回收之前它才會被調用。傳統標簽的處理器是單例的,只會被創建和銷毀一次。

          接下來,通過實現自定義標簽,學習如何使用BodyTag接口將標簽體中的小寫英文字母轉換為大寫,具體步驟如下。

          (1)編寫標簽處理器類ToUpperCase.java。

          JSP規范中定義了一個類BodyTagSupport實現了BodyTag接口,為了簡化程序的編寫,標簽處理器類ToUpperCase.java只需要繼承BodyTagSupport類即可。ToUpperCase.java類的實現代碼如下例所示。

          package cn.itcast.chapter09.classisctag;
          import java.io.IOException;
          import javax.servlet.jsp.JspException;
          import javax.servlet.jsp.tagext.BodyTagSupport;
          public class ToUpperCase extends BodyTagSupport {
              //定義doEndTag()方法
              public int doEndTag() throws JspException {
                  //獲取級沖區中數據
                  String content = getBodyContent().getString();
                  //將數據轉為大寫
                  content = content.toUpperCase();
                  try{
                      //輸出數據內容(兩種方式均可)
                      //pageContext.getout().write(content);
                      bodyContent.getEnclosingWriter().write(content);
                  } catch(IOException e){
                      e.printStackTrace();
                      return super.doEndTag();
                  }
          }

          由于BodyTagSupport類中的doStartTag()方法默認返回EVAL_BODY_BUFFERED常量,JSP容器會在執行標簽體之前創建BodyContent對象,然后將標簽體內容通過setBodyContent()方法設置給BodyContent對象。因此在上面案例中的doEndTag()方法中可以直接使用getBodyContent()方法的getString()方法獲得寫人到BodyContent緩沖區中的內容,然后將其轉換為大寫,通過調用getEnclosingWriter()方法獲取到out對象,將內容輸出到瀏覽器中。

          注意:不能直接使用doStartTag()方法的原因是,執行doStartTag()方法時,BodyContent對象中還沒有緩存標簽體的內容,因此通過getBodyContent()方法還無法獲得標簽的內容。

          (2)注冊標簽處理器類。

          在mytag.tld文件中增加一個Tag元素,對標簽處理器類進行注冊,注冊信息如下所示。

          <tag>
              <name>toUpperCase</name>
              <tag-class> cn.itcast.chapter09.classisctag.ToUpperCase</tag-class>
              <body-content>JSP</body-content>
          </tag>

          (3)編寫JSP頁面toUpperCase.jsp

          在JSP頁面中使用標簽,在標簽體中寫人26個小寫的英文字母,如下例所示。

          <%@page language="java" pageEncoding="GBK"%>
          <%@taglib uri= "http://www.itcast.cn" prefix="itcast"%>
          <html>
              <head>
              <title>HelloWorld Tag</title>
          </head>
          <body>
              <itcast: toUpperCase>
                  abcde fghij klmnopqrstuvwxyz
              </itcast:toUpperCase>
          </body>
          </html>

          (4)啟動Tomcat服務器,在瀏覽器地址欄中輸人URL地址“http://localhost:8080/chapter09/toUpperCase.jsp”訪問toUpperCase.jsp頁面,從運行結果可以看出,自定義標簽成功地將標簽體中的小寫英文字母轉換為大寫。


          主站蜘蛛池模板: 亚洲一区无码中文字幕| 久久无码人妻一区二区三区| 美女视频一区三区网站在线观看| 精品免费国产一区二区| 极品尤物一区二区三区| 高清国产AV一区二区三区| 人妻体内射精一区二区| 狠狠综合久久av一区二区| 亚洲字幕AV一区二区三区四区| 日韩精品视频一区二区三区 | 免费精品一区二区三区第35| 无码国产亚洲日韩国精品视频一区二区三区| 国产高清在线精品一区| 国产成人一区二区三区视频免费 | 精品熟人妻一区二区三区四区不卡 | 日本不卡一区二区三区视频| 国产色精品vr一区区三区| 免费无码一区二区| 无码人妻AⅤ一区二区三区水密桃| 中文字幕乱码人妻一区二区三区 | 日韩一区二区三区在线| 无码人妻久久一区二区三区免费丨| 日韩爆乳一区二区无码| 人妻少妇久久中文字幕一区二区 | 国产综合精品一区二区三区| 中文字幕一区在线| 日韩免费观看一区| 精品无码一区二区三区爱欲九九 | 国偷自产Av一区二区三区吞精| 成人国产一区二区三区| 日本不卡一区二区三区| 精品无人区一区二区三区在线| 亚洲AV日韩综合一区尤物| 国产成人精品一区二三区熟女 | 一区国严二区亚洲三区| 中文字幕在线无码一区| 日本中文字幕一区二区有码在线| 人妻AV中文字幕一区二区三区| 无码人妻精品一区二区蜜桃 | 日韩免费一区二区三区在线| 在线免费视频一区二区|