JAVADREAM

          hackiller
          <2009年8月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          統(tǒng)計(jì)

          • 隨筆 - 9
          • 文章 - 0
          • 評(píng)論 - 13
          • 引用 - 0

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          J2EE復(fù)習(xí)(六)JSP自定義標(biāo)簽

          一、JSP自定義標(biāo)簽簡(jiǎn)介
          標(biāo)簽是一種XML元素,通過標(biāo)簽可以使JSP網(wǎng)頁變得簡(jiǎn)潔并且易于維護(hù),還可以方便地實(shí)現(xiàn)同一個(gè)JSP文件支持多種語言版本。由于標(biāo)簽是XML元素,所以它的名稱和屬性都是大小寫敏感的
          標(biāo)準(zhǔn)JSP標(biāo)簽是用來調(diào)用JavaBean組件的操作,處理定向請(qǐng)求以簡(jiǎn)化JSP頁面開發(fā)與維護(hù)。JSP技術(shù)提供了一種封裝其它動(dòng)態(tài)類型的機(jī)制——自定義標(biāo)簽,它擴(kuò)展了JSP語言。自定義標(biāo)簽通常發(fā)布在標(biāo)簽庫中,該庫定義了一個(gè)自定義標(biāo)簽集并包含實(shí)現(xiàn)標(biāo)簽的對(duì)象。
          自定義標(biāo)簽是用戶定義的JSP語言元素。當(dāng)JSP頁面包含一個(gè)自定義標(biāo)簽時(shí)被轉(zhuǎn)化為servlet,標(biāo)簽轉(zhuǎn)化為對(duì)稱為tag handler的對(duì)象的操作。接著當(dāng)servlet執(zhí)行時(shí)Web container調(diào)用那些操作。

          二、兩種標(biāo)簽
          可以定義兩種類型的標(biāo)簽:
          javax.servlet.jsp.tagext.Tag
          javax.servlet.jsp.tagext.BodyTag

          有標(biāo)簽體的標(biāo)簽必須實(shí)現(xiàn) BodyTag 接口。

          <jsptag:map scope=“session” name=“tagMap”>
          body
          </jsptag:map>

          也可能沒有標(biāo)簽體:

          <jsptag:map/>

          無標(biāo)簽體的簡(jiǎn)單標(biāo)簽可以實(shí)現(xiàn) Tag 接口。

          三、標(biāo)簽處理程序
          int doStartTag() throws JspException---處理開始標(biāo)簽
          int doEndTag() throws JspException---處理結(jié)束標(biāo)簽
          Tag getParent()/void setParent(Tag t)---獲得/設(shè)置標(biāo)簽的父標(biāo)簽
          void setPageContext(PageContext pc)--- pageContext 屬性的 setter 方法
          void release() 釋放獲得的所有資源

          doStartTag()和doEndTag()方法的返回值說明:
          SKIP_BODY      表示不用處理標(biāo)簽體,直接調(diào)用doEndTag()方法。
          SKIP_PAGE      忽略標(biāo)簽后面的jsp(SUN企業(yè)級(jí)應(yīng)用的首選)內(nèi)容。
          EVAL_PAGE      處理標(biāo)簽后,繼續(xù)處理jsp(SUN企業(yè)級(jí)應(yīng)用的首選)后面的內(nèi)容。
          EVAL_BODY_BUFFERED 表示需要處理標(biāo)簽體,且需要重新創(chuàng)建一個(gè)緩沖(調(diào)用setBodyContent方法)。
          EVAL_BODY_INCLUDE  表示在現(xiàn)有的輸出流對(duì)象中處理標(biāo)簽體,但繞過setBodyContent()和doInitBody()方法
          EVAL_BODY_AGAIN     對(duì)標(biāo)簽體循環(huán)處理。(存在于javax.servlet.jsp.tagext.IterationTag接口中)

          實(shí)現(xiàn)javax.servlet.jsp.tagext.Tag接口
          擴(kuò)展javax.servlet.jsp.tagext.TagSupport類
          TagSupport 類定義了 get/setParent() 和 setPageContext(),這與所有標(biāo)簽處理程序幾乎相同。
          get/setParent() 方法允許標(biāo)簽嵌套。
          TagSupport 類還定義了一個(gè)可以被子類使用的 pageContext 實(shí)例變量 (protected PageContext pageContext),這個(gè)變量是由 setPageContext() 方法設(shè)置的。

          在創(chuàng)建自定義標(biāo)簽之前,需要?jiǎng)?chuàng)建一個(gè) 標(biāo)簽處理程序。標(biāo)簽處理程序是一個(gè)執(zhí)行自定義標(biāo)簽操作的 Java 對(duì)象。在使用自定義標(biāo)簽時(shí),要導(dǎo)入一個(gè) 標(biāo)簽庫 —— 即一組標(biāo)簽/標(biāo)簽處理程序?qū)ΑMㄟ^在 Web 部署描述符中聲明庫導(dǎo)入它,然后用指令 taglib 將它導(dǎo)入 JSP 頁。

          如果 JSP 容器在轉(zhuǎn)換時(shí)遇到了自定義標(biāo)簽,那么它就檢查 標(biāo)簽庫描述符(tag library descriptor) (TLD) 文件以查詢相應(yīng)的標(biāo)簽處理程序。TLD 文件對(duì)于自定義標(biāo)簽處理程序,就像 Web 部署描述符對(duì)于 servlet 一樣。

          在運(yùn)行時(shí),JSP 頁生成的 servlet 得到對(duì)應(yīng)于這一頁面所使用的標(biāo)簽的標(biāo)簽處理程序的一個(gè)實(shí)例。生成的 servlet 用傳遞給它的屬性初始化標(biāo)簽處理程序。
          標(biāo)簽處理程序?qū)崿F(xiàn)了 生存周期 方法。生成的 servlet 用這些方法通知標(biāo)簽處理程序應(yīng)當(dāng)啟動(dòng)、停止或者重復(fù)自定義標(biāo)簽操作。生成的 servlet 調(diào)用這些生存周期方法執(zhí)行標(biāo)簽的功能。

          四、TLD 文件
          TLD 文件的根元素是 taglib。taglib 描述了一個(gè) 標(biāo)簽庫 —— 即一組標(biāo)簽/標(biāo)簽處理程序?qū)Α?
          因?yàn)槲覀兪褂玫氖?JSP 版本 1.2,所以在這個(gè)例子中需要 tlib-version 和 short-name 元素。
          tlib-version 元素對(duì)應(yīng)于標(biāo)簽庫版本。
          jsp-version 對(duì)應(yīng)于標(biāo)簽庫所依賴的 JSP 技術(shù)的版本。
          short-name 元素定義了 IDE 和其他開發(fā)工具可以使用的標(biāo)簽庫的簡(jiǎn)單名。
          taglib 元素包含許多 tag 元素,標(biāo)簽庫中每一個(gè)標(biāo)簽有一個(gè) tag 元素。
          在JSP中導(dǎo)入TLD文件:

          <%@ taglib uri="firstTag" prefix="my"%>


          五、編寫自定義迭代標(biāo)簽和el表達(dá)式調(diào)用類的靜態(tài)方法實(shí)例

          循環(huán)標(biāo)簽體類:ForEach.java

           1import java.util.Collection;
           2import java.util.Iterator;
           3
           4import javax.servlet.jsp.JspException;
           5import javax.servlet.jsp.tagext.BodyContent;
           6import javax.servlet.jsp.tagext.BodyTagSupport;
           7
           8public class ForEach  extends BodyTagSupport
           9{
          10  private String id;
          11  private String collection;
          12  private Iterator iter;
          13  
          14  public void setCollection(String collection)
          15  {
          16    this.collection = collection;
          17  }

          18  public void setId(String id)
          19  {
          20    this.id = id;
          21  }

          22  
          23  //遇到開始標(biāo)簽執(zhí)行
          24  public int doStartTag() throws JspException
          25  {
          26    Collection coll = (Collection) pageContext.findAttribute(collection);
          27    // 表示如果未找到指定集合,則不用處理標(biāo)簽體,直接調(diào)用doEndTag()方法。
          28    if(coll==null||coll.isEmpty()) return SKIP_BODY;
          29    
          30    iter = coll.iterator();
          31    pageContext.setAttribute(id, iter.next());
          32    // 表示在現(xiàn)有的輸出流對(duì)象中處理標(biāo)簽體,但繞過setBodyContent()和doInitBody()方法
          33    // 這里一定要返回EVAL_BODY_INCLUDE,否則標(biāo)簽體的內(nèi)容不會(huì)在網(wǎng)頁上輸出顯示
          34    return EVAL_BODY_INCLUDE;
          35  }

          36  
          37  //在doInitBody方法之前執(zhí)行,在這里被繞過不執(zhí)行
          38  @Override
          39  public void setBodyContent(BodyContent arg0)
          40  {
          41    System.out.println("setBodyContent");
          42    super.setBodyContent(arg0);
          43  }

          44  //此方法被繞過不會(huì)被執(zhí)行
          45  @Override
          46  public void doInitBody() throws JspException
          47  {
          48    System.out.println("doInitBody");
          49    super.doInitBody();
          50  }

          51  
          52  //遇到標(biāo)簽體執(zhí)行
          53  public int doAfterBody() throws JspException
          54  {
          55    if(iter.hasNext()) 
          56    {
          57      pageContext.setAttribute(id, iter.next());
          58      return EVAL_BODY_AGAIN;// 如果集合中還有對(duì)像,則循環(huán)執(zhí)行標(biāo)簽體
          59    }

          60    return SKIP_BODY;//迭代完集合后,跳過標(biāo)簽體,調(diào)用doEndTag()方法。
          61  }

          62  
          63  //遇到結(jié)束標(biāo)簽執(zhí)行
          64  public int doEndTag() throws JspException
          65  {
          66    System.out.println("doEndTag");
          67    return EVAL_PAGE;
          68  }

          69
          70}

          獲取VO屬性類:GetProperty.java

           1import java.lang.reflect.Method;
           2
           3import javax.servlet.jsp.JspException;
           4import javax.servlet.jsp.tagext.BodyTagSupport;
           5
           6public class GetProperty extends BodyTagSupport
           7{
           8
           9  private String name;
          10  private String property;
          11
          12  public void setName(String name)
          13  {
          14    this.name = name;
          15  }

          16
          17  public void setProperty(String property)
          18  {
          19    this.property = property;
          20  }

          21
          22  @SuppressWarnings("unchecked")
          23  public int doStartTag() throws JspException
          24  {
          25    try
          26    {
          27      Object obj = pageContext.findAttribute(name);
          28      
          29      if (obj == nullreturn SKIP_BODY;
          30      
          31      Class c = obj.getClass();
          32      //構(gòu)造GET方法名字 get+屬性名(屬性名第一個(gè)字母大寫)
          33      String getMethodName = "get" + property.substring(01).toUpperCase() 
          34                              + property.substring(1, property.length());
          35      Method getMethod = c.getMethod(getMethodName, new Class[]{});
          36      
          37      pageContext.getOut().print(getMethod.invoke(obj));
          38      System.out.print(property + ":" + getMethod.invoke(obj) + "\t");
          39    }
           catch (Exception e)
          40    {
          41      e.printStackTrace();
          42    }

          43    return SKIP_BODY;
          44  }

          45
          46  public int doEndTag() throws JspException
          47  {
          48    return EVAL_PAGE;
          49  }

          50}

          51
          52表達(dá)式直接訪問此類中靜態(tài)的方法:ELFunction.java
          53public class ELFunction 
          54{
          55 public static int add( int i,int j )
          56 {
          57  return i+j;
          58 }

          59}

          寫一個(gè)測(cè)試用的VO類:UserVo.java

           1public class UserVo
           2{
           3  private String name;
           4  private String password;
           5  
           6  public String getName()
           7  {
           8    return name;
           9  }

          10  public void setName(String name)
          11  {
          12    this.name = name;
          13  }

          14  public String getPassword()
          15  {
          16    return password;
          17  }

          18  public void setPassword(String password)
          19  {
          20    this.password = password;
          21  }

          22}

          建好TLD文件tag.tld,放在WEB-INF目錄下

           1<?xml version="1.0" encoding="utf-8"?>
           2<taglib version="2.0"
           3 xmlns="http://java.sun.com/xml/ns/j2ee"
           4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           5 xmlns:shcemalocation="http://java.sun.com/xml/ns/j2ee 
           6 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
           7 
           8 <description>自定義標(biāo)簽</description>
           9 <display-name>JSTL core</display-name>
          10 <tlib-version>1.1</tlib-version>
          11 <short-name>firstLabel</short-name>
          12 <uri>http://java.sun.com/jsp/jstl/core</uri>
          13 
          14 <!-- 創(chuàng)建自定義 迭代標(biāo)簽 -->
          15 <tag>
          16  <name>forEach</name>
          17  <tag-class>exercise.taglib.ForEach</tag-class>
          18  <!-- 如果沒有標(biāo)簽體,設(shè)置empty , 如果有標(biāo)簽休必須設(shè)置JSP-->
          19  <body-content>JSP</body-content>
          20  <attribute>
          21   <name>id</name>
          22   <required>true</required><!-- 標(biāo)識(shí)屬性是否是必須的 -->
          23   <rtexprvalue>true</rtexprvalue><!-- 標(biāo)識(shí)屬性值是否可以用表達(dá)式語言 -->
          24  </attribute>
          25  <attribute>
          26   <name>collection</name>
          27   <required>true</required>
          28   <rtexprvalue>true</rtexprvalue>
          29  </attribute>
          30 </tag>
          31 
          32 <!-- 創(chuàng)建自定義獲得屬性標(biāo)簽 -->
          33 <tag>
          34  <name>getProperty</name>
          35  <tag-class>exercise.taglib.GetProperty</tag-class>
          36  <body-content>empty</body-content>
          37  <attribute>
          38   <name>name</name>
          39   <required>true</required>
          40   <rtexprvalue>true</rtexprvalue>
          41  </attribute>
          42  <attribute>
          43   <name>property</name>
          44   <required>true</required>
          45   <rtexprvalue>true</rtexprvalue>
          46  </attribute>
          47 </tag>
          48 
          49 <!-- 配置一個(gè)表達(dá)式調(diào)用 的函數(shù) -->
          50    <function>
          51     <name>add</name><!-- 配置一個(gè)標(biāo)簽,在JSP頁面通過引用前綴調(diào)用 -->
          52     <function-class>exercise.taglib.ELFunction</function-class><!-- 實(shí)現(xiàn)類 -->
          53     <function-signature>int add(int,int)</function-signature><!-- 靜態(tài)的方法:包括返回類型,方法名,入?yún)⒌念愋?nbsp;-->
          54    </function>
          55</taglib>

          在web.xml文件中配置自定義標(biāo)簽

          1<jsp-config>
          2 <taglib>
          3  <taglib-uri>firstTag</taglib-uri>
          4  <taglib-location>/WEB-INF/tag.tld</taglib-location>
          5 </taglib>
          6</jsp-config>

          在jsp文件中使用標(biāo)簽:tag.jsp

           1<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
           2<%@ taglib uri="firstTag" prefix="my"%>
           3
           4<jsp:useBean id="userVo1" class="exercise.vo.UserVo" scope="request">
           5  <jsp:setProperty name="userVo1" property="name" value="Hackiller"/>
           6  <jsp:setProperty name="userVo1" property="password" value="123"/>
           7</jsp:useBean>
           8
           9<jsp:useBean id="userVo2" class="exercise.vo.UserVo" scope="request">
          10  <jsp:setProperty name="userVo2" property="name" value="YangYang"/>
          11  <jsp:setProperty name="userVo2" property="password" value="456"/>
          12</jsp:useBean>
          13
          14<%
          15 List list = new ArrayList();
          16 list.add(userVo1);
          17 list.add(userVo2);
          18 pageContext.setAttribute("voList",list);
          19
          %>
          20
          21<html>
          22  <head>
          23    <title>My JSP 'tag.jsp' starting page</title>
          24  </head>
          25  
          26  <body>
          27    <h2 align="center">This is my JSP page:測(cè)試taglib.</h2> 
          28    <hr>
          29    
          30   <h2>自定義迭代標(biāo)簽:</h2>
          31    <table>
          32     <tr><td>姓名</td><td>密碼</td></tr>
          33     <my:forEach collection="voList" id="uservo">
          34      <tr>
          35       <td><my:getProperty name="uservo" property="name"/></td>
          36       <td><my:getProperty name="uservo" property="password"/></td>
          37      </tr>
          38     </my:forEach>
          39    </table>
          40    <hr>
          41    
          42    <h2>表達(dá)式調(diào)用類的靜態(tài)方法:</h2>
          43    2+5=${my:add(2,5)} 
          44  </body>
          45</html>


           

          posted on 2009-04-14 12:01 hackiller 閱讀(2497) 評(píng)論(2)  編輯  收藏 所屬分類: J2EE第一次復(fù)習(xí)

          評(píng)論

          # re: J2EE復(fù)習(xí)(六)JSP自定義標(biāo)簽 2009-08-06 16:34 人稱K哥

          不錯(cuò) 好東西

          # re: J2EE復(fù)習(xí)(六)JSP自定義標(biāo)簽 2012-05-08 09:35 0o明天會(huì)更好o0

          你好,請(qǐng)問你在標(biāo)簽方法實(shí)現(xiàn)類里,這樣去定義public static String getXml(String file,String culonm)

          在.tld文件里這樣去配置的,
          <function-signature>String getXml(String,String)</function-signature> name和class文件都沒什么

          在映射的方法enum里抱這個(gè)錯(cuò),求指導(dǎo)!

          Syntax error on token "String", ; expected after this token
          主站蜘蛛池模板: 和顺县| 吉木乃县| 江永县| 诸城市| 柘荣县| 施秉县| 盖州市| 荣成市| 响水县| 江阴市| 新疆| 工布江达县| 登封市| 涞源县| 蓬安县| 林甸县| 姚安县| 郓城县| 旺苍县| 左云县| 象州县| 读书| 泽州县| 海林市| 安新县| 蒲城县| 鄂温| 定兴县| 许昌市| 台前县| 泰州市| 尤溪县| 东台市| 房山区| 建始县| 泊头市| 习水县| 澳门| 临猗县| 和静县| 珠海市|