<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JAVADREAM

    hackiller
    數據加載中……
    J2EE復習(六)JSP自定義標簽

    一、JSP自定義標簽簡介
    標簽是一種XML元素,通過標簽可以使JSP網頁變得簡潔并且易于維護,還可以方便地實現同一個JSP文件支持多種語言版本。由于標簽是XML元素,所以它的名稱和屬性都是大小寫敏感的
    標準JSP標簽是用來調用JavaBean組件的操作,處理定向請求以簡化JSP頁面開發與維護。JSP技術提供了一種封裝其它動態類型的機制——自定義標簽,它擴展了JSP語言。自定義標簽通常發布在標簽庫中,該庫定義了一個自定義標簽集并包含實現標簽的對象。
    自定義標簽是用戶定義的JSP語言元素。當JSP頁面包含一個自定義標簽時被轉化為servlet,標簽轉化為對稱為tag handler的對象的操作。接著當servlet執行時Web container調用那些操作。

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

    有標簽體的標簽必須實現 BodyTag 接口。

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

    也可能沒有標簽體:

    <jsptag:map/>

    無標簽體的簡單標簽可以實現 Tag 接口。

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

    doStartTag()和doEndTag()方法的返回值說明:
    SKIP_BODY      表示不用處理標簽體,直接調用doEndTag()方法。
    SKIP_PAGE      忽略標簽后面的jsp(SUN企業級應用的首選)內容。
    EVAL_PAGE      處理標簽后,繼續處理jsp(SUN企業級應用的首選)后面的內容。
    EVAL_BODY_BUFFERED 表示需要處理標簽體,且需要重新創建一個緩沖(調用setBodyContent方法)。
    EVAL_BODY_INCLUDE  表示在現有的輸出流對象中處理標簽體,但繞過setBodyContent()和doInitBody()方法
    EVAL_BODY_AGAIN     對標簽體循環處理。(存在于javax.servlet.jsp.tagext.IterationTag接口中)

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

    在創建自定義標簽之前,需要創建一個 標簽處理程序。標簽處理程序是一個執行自定義標簽操作的 Java 對象。在使用自定義標簽時,要導入一個 標簽庫 —— 即一組標簽/標簽處理程序對。通過在 Web 部署描述符中聲明庫導入它,然后用指令 taglib 將它導入 JSP 頁。

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

    在運行時,JSP 頁生成的 servlet 得到對應于這一頁面所使用的標簽的標簽處理程序的一個實例。生成的 servlet 用傳遞給它的屬性初始化標簽處理程序。
    標簽處理程序實現了 生存周期 方法。生成的 servlet 用這些方法通知標簽處理程序應當啟動、停止或者重復自定義標簽操作。生成的 servlet 調用這些生存周期方法執行標簽的功能。

    四、TLD 文件
    TLD 文件的根元素是 taglib。taglib 描述了一個 標簽庫 —— 即一組標簽/標簽處理程序對。
    因為我們使用的是 JSP 版本 1.2,所以在這個例子中需要 tlib-version 和 short-name 元素。
    tlib-version 元素對應于標簽庫版本。
    jsp-version 對應于標簽庫所依賴的 JSP 技術的版本。
    short-name 元素定義了 IDE 和其他開發工具可以使用的標簽庫的簡單名。
    taglib 元素包含許多 tag 元素,標簽庫中每一個標簽有一個 tag 元素。
    在JSP中導入TLD文件:

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


    五、編寫自定義迭代標簽和el表達式調用類的靜態方法實例

    循環標簽體類: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  //遇到開始標簽執行
    24  public int doStartTag() throws JspException
    25  {
    26    Collection coll = (Collection) pageContext.findAttribute(collection);
    27    // 表示如果未找到指定集合,則不用處理標簽體,直接調用doEndTag()方法。
    28    if(coll==null||coll.isEmpty()) return SKIP_BODY;
    29    
    30    iter = coll.iterator();
    31    pageContext.setAttribute(id, iter.next());
    32    // 表示在現有的輸出流對象中處理標簽體,但繞過setBodyContent()和doInitBody()方法
    33    // 這里一定要返回EVAL_BODY_INCLUDE,否則標簽體的內容不會在網頁上輸出顯示
    34    return EVAL_BODY_INCLUDE;
    35  }

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

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

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

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

    62  
    63  //遇到結束標簽執行
    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      //構造GET方法名字 get+屬性名(屬性名第一個字母大寫)
    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表達式直接訪問此類中靜態的方法:ELFunction.java
    53public class ELFunction 
    54{
    55 public static int add( int i,int j )
    56 {
    57  return i+j;
    58 }

    59}

    寫一個測試用的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>自定義標簽</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 <!-- 創建自定義 迭代標簽 -->
    15 <tag>
    16  <name>forEach</name>
    17  <tag-class>exercise.taglib.ForEach</tag-class>
    18  <!-- 如果沒有標簽體,設置empty , 如果有標簽休必須設置JSP-->
    19  <body-content>JSP</body-content>
    20  <attribute>
    21   <name>id</name>
    22   <required>true</required><!-- 標識屬性是否是必須的 -->
    23   <rtexprvalue>true</rtexprvalue><!-- 標識屬性值是否可以用表達式語言 -->
    24  </attribute>
    25  <attribute>
    26   <name>collection</name>
    27   <required>true</required>
    28   <rtexprvalue>true</rtexprvalue>
    29  </attribute>
    30 </tag>
    31 
    32 <!-- 創建自定義獲得屬性標簽 -->
    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 <!-- 配置一個表達式調用 的函數 -->
    50    <function>
    51     <name>add</name><!-- 配置一個標簽,在JSP頁面通過引用前綴調用 -->
    52     <function-class>exercise.taglib.ELFunction</function-class><!-- 實現類 -->
    53     <function-signature>int add(int,int)</function-signature><!-- 靜態的方法:包括返回類型,方法名,入參的類型 -->
    54    </function>
    55</taglib>

    在web.xml文件中配置自定義標簽

    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文件中使用標簽: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:測試taglib.</h2> 
    28    <hr>
    29    
    30   <h2>自定義迭代標簽:</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>表達式調用類的靜態方法:</h2>
    43    2+5=${my:add(2,5)} 
    44  </body>
    45</html>


     

    posted on 2009-04-14 12:01 hackiller 閱讀(2494) 評論(2)  編輯  收藏 所屬分類: J2EE第一次復習

    評論

    # re: J2EE復習(六)JSP自定義標簽 2009-08-06 16:34 人稱K哥

    不錯 好東西
      回復  更多評論    

    # re: J2EE復習(六)JSP自定義標簽 2012-05-08 09:35 0o明天會更好o0

    你好,請問你在標簽方法實現類里,這樣去定義public static String getXml(String file,String culonm)

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

    在映射的方法enum里抱這個錯,求指導!

    Syntax error on token "String", ; expected after this token
      回復  更多評論    
    主站蜘蛛池模板: 国产亚洲精品岁国产微拍精品| 亚洲成a人片77777老司机| 特黄特色的大片观看免费视频| 国产日韩在线视频免费播放| 免费鲁丝片一级观看| 91亚洲国产成人久久精品| 真实乱视频国产免费观看| 三级网站免费观看| 一区二区亚洲精品精华液| 亚洲啪啪AV无码片| 成年女人毛片免费播放视频m | 在线观看免费黄色网址| 亚洲国产美女在线观看| 亚洲国产天堂久久久久久| 亚洲电影免费观看| 国产精品免费久久| 亚洲人成色777777老人头| 亚洲第一精品在线视频| 免费人成网站7777视频| av无码国产在线看免费网站| 亚洲高清免费视频| 亚洲爆乳精品无码一区二区| 亚洲久本草在线中文字幕| 免费在线观看你懂的| 在线v片免费观看视频| 日韩免费电影网址| 国产高潮久久免费观看| 亚洲中文字幕久久无码| 亚洲日本一区二区| 亚洲中文字幕第一页在线| 国产高清免费在线| 一进一出60分钟免费视频| 亚洲五月综合缴情婷婷| 久久精品亚洲日本佐佐木明希| 四虎永久免费地址在线网站| 7723日本高清完整版免费| 一级毛片在线免费看| 一级女性全黄久久生活片免费| 亚洲人成电影网站免费| 亚洲一级高清在线中文字幕| 亚洲第一精品在线视频|