<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 閱讀(2495) 評論(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
      回復  更多評論    
    主站蜘蛛池模板: 免费人成激情视频| 一个人看的hd免费视频| 一个人免费播放在线视频看片 | 国产小视频免费观看| 亚洲欧洲国产成人精品| 日韩免费无码一区二区三区| 国产V亚洲V天堂无码| 三年片在线观看免费| 中文字幕在线亚洲精品| 国产精品小视频免费无限app| 亚洲色偷偷狠狠综合网| 一级黄色免费网站| 亚洲美女视频网站| aa级一级天堂片免费观看| 亚洲黄页网在线观看| 在线观看亚洲免费| 污污视频免费观看网站| 亚洲天堂免费在线视频| 日本妇人成熟免费中文字幕| 亚洲欧美日韩中文字幕一区二区三区| 免费无码黄网站在线观看| 男女猛烈xx00免费视频试看| 亚洲色图综合在线| 免费看污成人午夜网站| 久久国产福利免费| 亚洲黄色免费电影| 亚洲精品视频免费| 亚洲精品免费在线观看| 亚洲国产成人久久综合一区| 免费观看男人免费桶女人视频| 久久这里只精品热免费99| 亚洲另类精品xxxx人妖| 日韩一卡2卡3卡4卡新区亚洲| 成人无码区免费视频观看| 日韩在线观看视频免费| 久久久亚洲欧洲日产国码农村| 麻豆一区二区免费播放网站| 三级毛片在线免费观看| 亚洲午夜电影一区二区三区| 国产精品亚洲一区二区三区在线| aⅴ免费在线观看|