官术网_书友最值得收藏!

4.3 JSP的自定義標簽

JSP中設計自定義標簽的目的就是為了實現HTML代碼的重用,許多公司已經有屬于自己的自定義標簽,將多樣化的表格、復雜的報表等封裝成自定義標簽,并逐步完善形成一個平臺,在此基礎上繼續進行程序開發,大大提高了開發的效率以及風險控制能力。

實例117 帶標簽體的自定義標簽

光盤位置:光盤\MR\04\117

初級

實用指數:

實例說明

本實例主要使用標簽體的getBodyContent()方法自定義一個標簽,把一段字母按大寫輸出,運行結果如圖4.27所示。

圖4.27 按大寫輸出結果

關鍵技術

使用BodyTagSupport類,再調用PageContent()方法,BodyTag接口除了常用的doStartTag()、doEndTag()之外,還有doInitBody(),該方法每次處理完標簽體都要被執行,重載這個方法來處理自己的標簽體,這個方法通常返回SKIP_BODY_TAG,指明沒有標簽體需要繼續處理,如果返回的是EVAL_BODY_TAG,則這個標簽體被再次處理,導致調用doAfterBody(),直到doAfterBody返回SKIP_BODY。

設計過程

(1)創建BodyTagSupport類的實現類TagBody.java,主要代碼如下:

        public class TagBody extends BodyTagSupport {
        public int doEndTag() throws JspException {
              String ct = this.getBodyContent().getString();
              //獲取標簽體的代碼
              try {
                  //以大寫輸出
                  this.pageContext.getOut().print(ct.toUpperCase());
              } catch (IOException e) {
              }
              return EVAL_PAGE;
        }
        }

(2)創建tagbody.tld文件,主要代碼如下:

        <tlib-version>1.0</tlib-version>
         <short-name>toUpperCase</short-name>
              <tag>
                  <name>toupp</name>
                  <tagclass>com.mr.bodycontent.TagBody</tagclass>
                  <bodycontent>JSP</bodycontent>
         </tag>

(3)創建index.jsp頁面,主要代碼如下:

        <body>
          <toUpperCase:toupp>hello welcome to mr networkschool! ! ! ! </toUpperCase:toupp>
         </body>

秘笈心法

當執行doStartTag()方法時,返回值若是EVAL_BODY_BUFFERED,則不會輸出;返回值如果是EVAL_BODY_INCLUDE,則會輸出標簽體內容。標簽體的內容是通過setBodyContent()方法添加到標簽類中的,可以使用getBodyContent()方法得到標簽體的內容。

實例118 自定義多次執行的循環標簽

光盤位置:光盤\MR\04\118

初級

實用指數:

實例說明

本實例定義了一個numbers變量進行自減運算,使用doAfterBody()方法來循環然后在頁面中輸出蘋果,效果如圖4.28所示。

圖4.28 運行結果

關鍵技術

本實例主要使用BodyTagSupport類的doAfterBody()方法,如果該方法返回Tag.SKIP_BODY,就不再執行標簽主體的內容;如果該方法返回IterationTag.EVAL_BODY_AGAIN,就繼續重復執行標簽主體的內容。

設計過程

(1)創建實現類Mul類,用doAfterBody()方法來控制單次執行還是多次執行,主要代碼如下:

        public class Mul extends BodyTagSupport {
        private int numbers;                 //定義變量numbers
        public int doStartTag() throws JspException {
              numbers=5;                   //初始值為5
              return super.doStartTag();
        }
        public int doAfterBody() throws JspException {
              if(numbers-->0){             //自減運算
                  try {
                      this.getPreviousOut()
                                .println(this.getBodyContent().getString());
                  } catch (Exception e) {
                  }
                  return EVAL_BODY_AGAIN;
              } else {
                  return SKIP_BODY;
              }
        }
        }

(2)創建mul.tld標簽,代碼如下:

        <tlib-version>1.0</tlib-version>
         <short-name>tagmul</short-name>
        <jspversion>1.1</jspversion>
          <tag>
                  <name>muls</name>
                  <tag-class>com.zm.Mul</tag-class>
                  <body-content>JSP</body-content>
        </tag>

(3)創建index.jsp頁面,使用<pre>迭代,主要代碼如下:

        <h3 align="center">
        <pre><tagmul:muls>蘋果</tagmul:muls></pre>
        </h3>

秘笈心法

帶標簽體的標簽大體可以分為單次執行(single Evaluation)和多次執行(multiple Evaluation)。單次執行指的是標簽體只會被使用一次,而多次執行是指標簽體可以被使用多次。

實例119 自定義顯示版權信息標簽

光盤位置:光盤\MR\04\119

初級

實用指數:

實例說明

本實例通過自定義一個標簽為Copyright和相對應的java類來實現,此類必須實現Tag接口,在JSP中執行自定義的標簽<taglib:copyright />來輸出定義好的版權內容,運行結果如圖4.29所示。

圖4.29 版權信息

關鍵技術

所有的標簽處理類都要實現JspTag接口。這個接口只是一個標識接口,沒有任何方法,主要是作為Tag和SimpleTag接口的共同接口。在JSP 2.0以前,所有的標簽處理類都要實現Tag接口,實現該接口的標簽為傳統標簽。Tag接口定義了所有傳統標簽處理類都要實現的基本方法,包括以下幾種。

? setPageContext(PageContext pc):由Servlet容器調用該方法,向當前標簽處理對象(即Tag對象)傳遞當前的PageContext對象。

? setParent(Tag t):由Servlet容器調用該方法,向當前Tag對象傳遞父標簽的Tag對象。

? getParent():返回Tag類型的父標簽的Tag對象。

? release():當Servlet容器需要釋放Tag對象占用的資源時,會調用此方法。

? doStartTag():當Servlet容器遇到標簽的起始標志時,會調用此方法。

? doEndTag():當Servlet容器遇到標簽的結束標志時,會調用此方法。

設計過程

(1)創建一個Copyright類,主要代碼如下:

        public class copyright implements Tag {
        private PageContext pageContext;                        //在JSP中顯示的內容
        public PageContext getPageContext() {
              return pageContext;
        }
        public void setPageContext(PageContext pageContext) {
              this.pageContext = pageContext;
        }
        public int doEndTag()throws JspException{              //標簽結束時執行
              JspWriter out=pageContext.getOut();                //獲取out對象
              try {
                  //輸出已定義的版權信息
                  out.println(ResourceBundle.getBundle("copyright").getString("copyright"));
              } catch (IOException e) {
                  throw new JspException(e);
              }
              return EVAL_PAGE;
        }
        public int doStartTag()throws JspException{           //標簽開始時執行
            return SKIP_BODY;
        }
        public void release(){
        }
        public Tag getParent(){
            return null;
        }
        public void setParent(Tag arg0){
        }
        }

(2)創建tld標簽庫描述文件,在/WEB-INF/下新建taglib.tld并添加以下代碼:

        <? xml version="1.0"encoding="UTF-8"? >
        <taglib version="2.0" 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 web-jsptaglibrary_2_0.xsd">
        <tlib-version>1.0</tlib-version>
        <jspversion>1.1</jspversion>
        <short-name>taglib</short-name>
        <uri>http://mingrisoft.com/tags</uri>
        <tag>
              <name>copyright</name>
              <tagclass>com.mr.tags.copyright</tagclass>
              <bodycontent>JSP</bodycontent>
        </tag>
        </taglib>

(3)創建copyright.jsp頁面,并添加剛定義好的標簽,主要代碼如下:

        <body>
              <taglib:copyright></taglib:copyright>
         </body>

秘笈心法

標簽處理類的對象(Tag對象)由Servlet容器負責創建。Servlet容器在執行JSP文件時,如果遇到JSP文件中的自定義標簽,就會尋找緩存中的相關Tag對象;如果還不存在,就創建一個Tag對象,把它存放在緩存中,以便下次處理自定義標簽時重復使用。

實例120 自定義圖片瀏覽標簽

光盤位置:光盤\MR\04\120

初級

實用指數:

實例說明

本實例介紹如何從服務器上獲得圖片文件并顯示給客戶端。運行本實例,在頁面中將顯示服務器中的指定圖片,如圖4.30所示。

圖4.30 圖片瀏覽標簽

關鍵技術

通過BufferedInputStream建立輸入流完成讀取文件的操作,其語法格式如下:

        FileInputStream in = new FileInputStream(new File(fileName))

參數說明

? fileName:文件的名稱。

? new File(fileName):建立文件名稱為fileName的文件。通過類BufferedInputStream建立緩沖輸入流,它的參數為FileInputStream。

設計過程

(1)創建imagetag.java類文件,此類繼承自SimpleTagSupport類。在該類中分別定義了兩個變量fileName和response,表示圖片的名稱和給予客戶端的響應,并在doTag()方法中完成圖片數據的傳輸,關鍵代碼如下:

        public class imagetag extends SimpleTagSupport {
              private String fileName;
              private HttpServletResponse response;
              public void setFileName(String fileName) {
                  this.fileName = fileName;
              }
              public void setResponse(HttpServletResponse response) {
                  this.response = response;
              }
              public void doTag(){
                  try {
                      FileInputStream in=new FileInputStream(new File(fileName));   //創建輸入流完成讀取文件
                      BufferedInputStream bufferin=new BufferedInputStream(in);     //創建緩沖輸入流參數為in
                      OutputStream out  =response.getOutputStream();                //向客戶端輸出流
                      BufferedOutputStream bufferout=new BufferedOutputStream(out); //創建緩沖輸出流參數為out
                      byte b[] = new byte[1024*5];
                      for(int i =bufferin.read(b); i! =-1; ){
                            bufferout.write(b);
                            bufferin.read(b);
                      }
                      bufferout.flush();
                      bufferout.close();
                      bufferin.close();
                      out.close();
                      in.close();
                  } catch (FileNotFoundException e) {
                      e.printStackTrace();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
        }

(2)創建標簽描述文件example.tld,相應地描述標簽類的配置,關鍵代碼如下:

        <tlib-version>1.0</tlib-version>
        <short-name>filetag</short-name>
        <tag>
                  <name>filetag</name>
                  <tag-class>com.mr.imagetag</tag-class>
                  <body-content>empty</body-content>
              <attribute>
                  <name>fileName</name>
                  <required>true</required>
                  <rtexprvalue>true</rtexprvalue>
              </attribute>
              <attribute>
                  <name>response</name>
                  <required>true</required>
                  <rtexprvalue>true</rtexprvalue>
                  </attribute>
        </tag>

(3)在web.xml中配置引導標簽類的地址和tld文件的位置,關鍵代碼如下:

        <jsp-config>
              <taglib>
                  <taglib-uri>/http://www.mingrisoft.com/tags</taglib-uri>
                  <taglib-location>/WEB-INF/example.tld</taglib-location>
              </taglib>
          </jsp-config>

(4)創建tagimage.jsp頁面,它的作用是引入自定義的圖片標簽,然后讀取服務器上的圖片并將其顯示在頁面上,關鍵代碼如下:

        <body>
              <filetag:filetag response="${pageContext.response}"
                  fileName='<%=pageContext.getServletContext().getRealPath("Hd.jpg") %>' />
        </body>

秘笈心法

文件流讀取完畢后,應該調用其close()方法及時關閉流,以免造成不必要的異常和占用不必要的內存空間。

實例121 自定義文件下載的標簽

光盤位置:光盤\MR\04\121

初級

實用指數:

實例說明

進行Web開發或者網站設計時,數據下載是經常會用到的功能,本實例通過SimpleTag類設計一個通用的文件下載標簽,完成文件下載功能。運行本實例,如圖4.31所示,單擊“下載”超鏈接即可下載指定文件。

圖4.31 自定義文件下載標簽

關鍵技術

在制作文件下載標簽時,最關鍵的步驟是實現文件下載功能,本實例實現文件下載的基本思路如下:

(1)通過request類中的getRealPath()方法獲得文件的真實路徑,即文件在服務器上的絕對路徑。

(2)通過response類中的setHeader()方法設置客戶端文件下載的路徑。

(3)通過文件類BufferedInputStream進行數據的讀入。

(4)通過BufferedOutputStream.java類進行數據的寫入,實現文件的下載。

設計過程

(1)創建DownTag.java類文件,此類繼承自SimpleTagSupport類,關鍵代碼如下:

        package com;
        import java.io.*;
        import javax.servlet.*;
        public class DownTag extends SimpleTagSupport {

首先,創建存放文件的名稱及相應的HttpServletResponse和HttpServletRequest類對象的屬性,并且設置相對應的get()/set()方法,關鍵代碼如下:

        private String fileName;                                                                        //文件的名稱
        private String fileType;                                                                        //文件的類型
        private HttpServletResponse response;                                                           //HttpServletResponse的屬性名稱
        private HttpServletRequest request;                                                             //HttpServletRequest的屬性名稱
        private String filePath=null;                                                                   //文件的路徑
        public void setRequest(HttpServletRequest request) {
        this.request = request;
        }
        public void setFileName(String filePath) {
        this.fileName = filePath;
        }
        public void setFileType(String fileType) {
        this.fileType = fileType;
        }
        public void setResponse(HttpServletResponse response) {
        this.response = response;
        }

然后,在doTag()方法中編寫實現文件下載的代碼,先設置客戶端要下載文件的位置,接著定義輸入緩沖流和輸出緩沖流進行文件的讀寫操作,關鍵代碼如下:

        public void doTag() throws JspException{
        filePath = request.getRealPath("/");
        response.setHeader("Content-disposition", "attachment; filename=" + fileName + "." + fileType);
        try {
              fileName=new String(fileName.getBytes("ISO-8859-1"), "GBK");                                    //文件名轉換編碼
              String convertfilepath=filePath.trim()+"download\\"  +fileName.trim()+"."+fileType.trim();
              File file=new File(convertfilepath.replaceAll("\\\\", "/"));                                     //替換路徑中的斜杠
              FileInputStream input=new FileInputStream(file);                                                 //實例化文件輸入流
              BufferedInputStream bufferinput=new BufferedInputStream(input);                                  //帶緩沖文件輸入流
              ServletOutputStream out=response.getOutputStream();                                             //獲取文件輸出流
              BufferedOutputStream bufferoutput=new BufferedOutputStream(response.getOutputStream());          //封裝文件輸入流
              byte[] temp = new byte[2048];
              int bytesRead;
              while ((bytesRead = (input.read(temp, 0, temp.length))) ! = -1 ) {
                  bufferoutput.write(temp, 0, bytesRead);
              }
              bufferoutput.flush();                                                                          //刷新
              if (input ! = null) {
                  input.close();                                                                             //關閉輸入流
              }
              if (bufferoutput ! = null) {
                  out.close();                                                                               //關閉文件輸出流
                  bufferoutput.close();                                                                      //關閉緩沖輸出流
              }
        } catch (Exception e) {
              e.printStackTrace();
        }
        }

(2)在WEB-INF目錄下編寫down.tld文件,完成標簽的配置,在這個配置中設置標簽中所使用的類文件以及這個類中的私有變量,關鍵代碼如下:

        <tag>
          <name>tagfile</name>
        <tag-class>com.DownTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
          <name>fileName</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
        <name>fileType</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
          <name>response</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
          <name>request</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
        </attribute>
        </tag>

(3)在web.xml文件中添加所使用的標簽,關鍵代碼如下:

        <taglib>
        <taglib-uri>/downtag</taglib-uri>
        <taglib-location>/WEB-INF/down.tld</taglib-location>
        </taglib>

(4)在Web根目錄下建立一個index.jsp文件,在這個文件中連接數據庫并顯示數據庫中要下載的文件信息,關鍵代碼如下:

        <form action="" method="post">
          <table width="639" border="1" cellspacing="0" cellpadding="0">
            <tr>
              <td width="54">編號</td>
              <td width="244">文件名稱</td>
              <td width="94">文件大小</td>
        <td width="64">文件類型</td>
        <td width="92">文件路徑</td>
        <td width="77">文件下載/td>
            </tr>
            <c:forEach var="collection" items="${collection}">
            <tr>
            <td><c:out value="${collection[0]}"/></td>
        <td><c:out value="${collection[1]}"/></td>
        <td><c:out value="${collection[2]}"/></td>
        <td><c:out value="${collection[3]}"/></td>
        <td><c:out value="${collection[4]}"/></td>
        <td align="center"><a href="downfile.jsp? name=${collection[1]}&type=${collection[3]}">下載</a></td>
          <down:tagfile />
            </tr>
            </c:forEach>
          </table>
          </form>

(5)在Web根目錄下創建downfile.jsp文件,完成文件下載功能,關鍵代碼如下:

        <down:tagfile fileName="${param['name']}" fileType="${param['type']}" response="<%=response%>" request="<%=request%>"/>

秘笈心法

在實現文件的下載功能時,應用該自定義標簽即可,這樣不僅可以提高代碼的可重用性,而且能夠提高項目的開發效率,避免在JSP中編寫大量的Java代碼。

實例122 自定義數據查詢的標簽

光盤位置:光盤\MR\04\122

初級

實用指數:

實例說明

本實例將介紹如何通過SimpleTag來制作通用的標簽。該方法實現的標簽可以移植到任何一個JSP頁面中,實例中定義的標簽接收SQL查詢語句作為參數,在使用時只需更改相應的參數即可實現不同的數據查詢功能,實例運行結果如圖4.32所示,頁面中顯示了標簽返回的用戶查詢結果。

圖4.32 自定義數據查詢標簽運行結果

關鍵技術

通過JspWriter.java類向頁面輸出表格,然后在表格中進行數據填充。獲取JspWriter對象的語法格式如下:

        JspWriter out = this.getJspContext().getOut();

設計過程

(1)創建DBCon.java類,用于創建數據庫連接,關鍵代碼如下:

        public class DBCon {
        public static Connection getConnection(){
              Connection conection = null;
              try{
                  Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");        //加載數據庫驅動類
                  conection = DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=db_database17 ", "sa", ""); //創建連接
            }catch(Exception e){
              e.printStackTrace();
            }
            return conection;
        }
        }

(2)創建TableTag.java類文件,此類繼承自SimpleTag類,關鍵代碼如下:

        import java.io.*;
        import java.sql.*;
        import javax.servlet.*;
        import javax.naming.*;
        public class TableTag extends SimpleTagSupport {
        //定義兩個變量分別用來存儲表格的標題名稱和查詢的SQL語句
        private String tableTitle[];                                                        //標題名稱定義為數組
        public void setTableTitle(String[] title) {
            this.tableTitle = title;
        }
        private String sqlSelect;                                                           //定義SQL語句
        public void setSqlSelect(String sql) {
            this.sqlSelect = sql;
        }
        public void doTag() {
        //獲取數據庫的連接并執行SQL語句
        connection=DBCon.getConnection();                                                 //獲取數據庫連接
        PreparedStatement pstmt=connection.prepareStatement(this.sqlSelect);               //執行SQL語句
        java.sql.ResultSet resultset=pstmt.executeQuery();                                 //獲取結果集
        ResultSetMetaData rsmd=resultset.getMetaData();                                    //獲取表結構對象
        //顯示表格的標題
              out.write("<table border=1 align='center'><tr bgcolor='#669966'  align='center'>");
              for (int i = 0 ; i < tableTitle.length ; i++){
                  try {
                      out.write("<td height='28'>"+tableTitle[i]+"</td>");                 //輸出表頭
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
              out.write("</tr>");
              while(resultset.next()){                                                    //循環輸出表中的記錄
                  out.write("<tr align='center' height='28px' >");
                  for ( int i = 1 ; i <= rsmd.getColumnCount() ; i ++){
                  out.write("<td>" + resultset.getObject(i).toString() + "</td>");
                  }
                  out.write("</tr>");
              }
              out.write("</table>");
          }catch(Exception sql){
              sql.printStackTrace();
          }finally{
            try{
                  if(connection! =null)
                  connection.close();
            }catch(SQLException e){
                  e.printStackTrace();
            }
          }
        }

(3)在WEB-INF目錄下建立tabletag.tld標簽文件,描述自定義的標簽及配置自定義標簽文件,關鍵代碼如下:

        <tag>
          <name>tbg</name>
        <tag-class>com.TableTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
        <name>tableTitle</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
        <name>sqlSelect</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
        </attribute>
        </tag>

(4)在web.xml配置文件中引入tabletag.tld標簽文件,關鍵代碼如下:

        <taglib>
        <taglib-uri>/tabletag</taglib-uri>
        <taglib-location>/WEB-INF/tabletag.tld</taglib-location>
        </taglib>

(5)創建index.jsp頁面文件,引入自定義的標簽后,先定義兩個參數用來為標簽屬性賦值,然后在這個頁面中使用該標簽,關鍵代碼如下:

        <%@ taglib uri="/WEB-INF/tabletag.tld" prefix="tagtable"%>
        <%
        String[] tableTitle = {"姓名", "性別", "年齡", "身份證號", "政治面貌", "家庭電話", "家庭地址"};
        String sqlSelect = "SELECT top 6 name, sex, age, sfzhm, zzmm, jtdh, jtdz FROM docu_stu_info ";
        request.setAttribute("title", tableTitle);
        request.setAttribute("sql", sqlSelect);
        %>
        <body>
            <tagtable:tbg tableTitle="${title}" sqlSelect="${sql}"/>
        </body>

秘笈心法

在實際項目開發過程中,經常需要進行數據查詢,而數據查詢的實現過程都是類似的,因此可以考慮實現一個公共的自定義查詢標簽,在查詢數據時,調用自定義標簽即可,這樣可以提高開發效率。

實例123 自定義生成隨機數的標簽

光盤位置:光盤\MR\04\123

初級

實用指數:

實例說明

JSP自定義標簽可以減少JSP頁面中嵌入的Java腳本,使得頁面程序易于維護,并提高代碼重用率。本實例使用自定義標簽在頁面中輸出一個用戶指定位數的隨機數,如圖4.33所示。

圖4.33 生成隨機數

關鍵技術

本實例中設計的標簽含有一個length屬性,這就需要在標簽處理類中定義一個相對應的屬性和get、set方法。另外,還需要在標簽描述文件中配置這個屬性。

設計過程

(1)編寫RandomNum.java類文件,繼承自TagSupport類,并在該類中編寫一個生成隨機數的方法createRandom(),在doEndTag()方法中調用該方法生成一個隨機數,關鍵代碼如下:

        public class RandomNum extends TagSupport {
        private static final long serialVersionUID = 1L;
        protected String length;                                             //標簽屬性
        public String getLength() {
              return length;
        }
        public void setLength(String length) {
              this.length = length;
        }
        public int createRandom(){                                           //根據長度生成一個隨機數
              int i = (int)(Math.random()*(Math.pow(10, Integer.parseInt(length))));
              return i;
        }
        public int doEndTag() throws JspException {
              try {
                  pageContext.getOut().print(createRandom());              //獲取輸出對象,輸出隨機數
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return super.doEndTag();
        }
        }

(2)在WEB-INF文件夾中編寫mytag.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 web-jsptaglibrary_2_0.xsd"
            version="2.0">
              <tlib-version>1.0</tlib-version>
              <short-name>mytag</short-name>
              <uri>http://www.tag.com/mytag</uri>
              <tag>
                  <description>生成隨機數</description><! -- 標簽描述 -->
                  <name>randomNum</name><! -- 標簽名稱 -->
              <tag-class>com.jwy.tag.RandomNum</tag-class><! -- 標簽路徑 -->
              <body-content>empty</body-content><! -- 標簽體 -->
              <attribute>
                  <name>length</name><! -- 屬性名稱 -->
                  <required>true</required><! -- 是否必須指定此屬性 -->
                  <rtexprvalue>true</rtexprvalue><! -- 是否能接受JSP表達式或EL表達式 -->
              </attribute>
              </tag>
        </taglib>

(3)在web.xml中對自定義標簽庫進行引用,關鍵代碼如下:

        <jsp-config>
            <taglib>
                  <taglib-uri>http://www.tag.com/mytag</taglib-uri>
                  <taglib-location>/WEB-INF/mytag.tld</taglib-location>
            </taglib>
        </jsp-config>

(4)編寫index.jsp頁面,在此頁面中使用自定義標簽,關鍵代碼如下:

        <body>
        <form action="index.jsp" method="post" name="f1">
              請選擇要生成的隨機數長度:
              <select name="len">
                  <option selected="selected" value="0">請選擇位數</option>
                  <option value="1">1</option>
                  <option value="2">2</option>
                  <option value="3">3</option>
                  <option value="4">4</option>
                  <option value="5">5</option>
                  <option value="6">6</option>
                  <option value="7">7</option>
                  <option value="8">8</option>
                  <option value="9">9</option>
                  <option value="10">10</option>
              </select>
              <input type="submit" value="生成">
        </form>
        <%
              if (request.getParameter("len")! =null&&! "0".equals(request.getParameter("len"))) {
        %>
        生成的隨機數為:
        <mytag:randomNum length='<%=request.getParameter("len")%>' />
        <%
              }
        %>
        </body>

秘笈心法

根據本實例的實現,讀者可以使用自定義標簽生成驗證碼。

實例124 自定義生成系統菜單的標簽

光盤位置:光盤\MR\04\124

初級

實用指數:

實例說明

本實例使用自定義標簽來生成產品分類導航目錄。運行本實例,如圖4.34所示,單擊產品類別名稱就可以看到該類別中的全部產品。

圖4.34 產品導航目錄

關鍵技術

如果要在頁面中使用自定義標簽,首先要在web.xml文件中對標簽庫進行引用聲明(具體代碼見設計過程步驟(4)),然后還要在頁面中引用標簽,關鍵代碼如下:

        <%@taglib prefix="mytag" uri="http://www.tag.com/mytag"%>

設計過程

(1)編寫MenuTag.java類文件,并讓該類繼承TagSupport類,然后重寫父類中的doStartTag()方法,并在此方法中調用自定義顯示菜單的方法,關鍵代碼如下:

        public class MenuTag extends TagSupport {
        public int doStartTag() throws JspException {
              HttpServletRequest request=(HttpServletRequest)pageContext.getRequest();    //創建request對象
              HttpSession session=request.getSession();                                   //創建session對象
              List list=(List)session.getAttribute("menuList");                           //獲取會話對象中保存的List列表
              loadMenu(list);                                                            //調用生成菜單的方法
              return super.doStartTag();
        }
        }

(2)在MenuTag類中編寫loadMenu()方法,該方法將List列表中保存的菜單內容顯示在頁面中,并將用戶選中的項目展開,關鍵代碼如下:

        private void loadMenu(List menuList) {
        JspWriter out=pageContext.getOut();                                               //獲取向頁面輸出的out對象
        HttpServletRequest request=(HttpServletRequest)pageContext.getRequest();          //創建request對象
        HttpSession session=request.getSession();                                         //創建session對象
        try {
              if (menuList.isEmpty()) {
                  out.write("<table><tr><td>沒有可以顯示的菜單</td></tr></table>");
              } else {
                  for(int i=0; i<menuList.size(); i++){                                   //循環List列表
                      List sList = (List) menuList.get(i);
                      out.write("<a href='index.jsp? id=" + i + "'>"+ sList.get(0) + "</a><br>");
                      if(pageContext.getRequest().getParameter("id")! =null){            //判斷是否被選中
                            if (Integer.parseInt(pageContext.getRequest().getParameter("id")) == i) {
                                for(int j=1; j<sList.size(); j++){                        //顯示子項目
                                      out.write("&nbsp; &nbsp; " + sList.get(j) + "<br>");
                                }
                            }
                      }
                  }
              }
        } catch (Exception e) {
              e.printStackTrace();
        }
        }

(3)編寫mytag.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 web-jsptaglibrary_2_0.xsd"
            version="2.0">
              <tlib-version>1.0</tlib-version>
              <short-name>mytag</short-name>
              <uri>http://www.tag.com/mytag</uri>
              <tag>
                  <description>生成菜單</description>
                  <name>nemuTag</name>
              <tag-class>com.jwy.tag.MenuTag</tag-class>
              <body-content>empty</body-content>
              </tag>
        </taglib>

(4)在web.xml配置文件中對標簽庫進行引用聲明,關鍵代碼如下:

        <jsp-config>
          <taglib>
          <taglib-uri>http://www.tag.com/mytag</taglib-uri>
          <taglib-location>/WEB-INF/mytag.tld</taglib-location>
          </taglib>
        </jsp-config>

(5)編寫index.jsp頁面文件,首先引入自定義標簽庫,然后在該文件中初始化一個List列表對象并保存到session對象中,最后調用該標簽,關鍵代碼如下:

        <%@page contentType="text/html" pageEncoding="GBK"%>
        <%@page import="java.util.*"%>
        <%@taglib prefix="mytag" uri="http://www.tag.com/mytag"%>
        <html>
        <body>
              <%
                  if (session.getAttribute("menuList") == null) {
                      List<List<String>> menuList = new ArrayList<List<String>>();
                      List<String> sList1 = new ArrayList<String>();
                      sList1.add("硬件");
                      sList1.add("顯示器");
                      sList1.add("主機");
                      sList1.add("顯卡");
                      sList1.add("CPU");
                      sList1.add("內存");
                      sList1.add("硬盤");
                      menuList.add(sList1);
                      List<String> sList2 = new ArrayList<String>();
                      sList2.add("外設");
                      sList2.add("鍵盤");
                      sList2.add("鼠標");
                      sList2.add("音箱");
                      sList2.add("耳機");
                      sList2.add("攝像頭");
                      menuList.add(sList2);
                      ……//省略部分代碼
                      session.setAttribute("menuList", menuList);
                  }
              %>
              產品導航目錄
              <br>
              <mytag:nemuTag />
        </body>
        </html>

秘笈心法

根據本實例,讀者可以編寫論壇中的功能菜單,還可以從數據庫中讀取菜單內容。

主站蜘蛛池模板: 汾阳市| 宁海县| 进贤县| 云龙县| 卓资县| 营山县| 天台县| 隆化县| 贺兰县| 兴海县| 灵台县| 琼结县| 茂名市| 新田县| 慈溪市| 天津市| 东乡县| 石城县| 历史| 华池县| 同心县| 滦平县| 桦南县| 承德市| 根河市| 洪江市| 彭州市| 镇赉县| 鹤庆县| 洪洞县| 德州市| 浏阳市| 凉山| 清丰县| 高陵县| 山东| 丰台区| 长丰县| 黔西县| 岚皋县| 安乡县|