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

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

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

    posts - 78, comments - 34, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

             除了JavaMail今日是JavaWeb部分的最后一天了,還有三天的時間是做個小項目。將之前學習的所有知識串起來,準備迎接高級部分。嘿嘿!終于到了高級部分!

             今日主要內容是JSP自定義標簽與JSTL,之前有使用過JSTL,十分的方便,還有EL。也有學過自定義EL函數,但個人感覺EL自定義函數沒有JSP的自定義標簽有趣。

    一、JSP自定義標簽

    我們知道,JSP在被訪問時會被JSP引擎翻譯為Servlet程序,即JSP就是Servlet程序。我們可以在JSP中插入Java代碼,但是在JSP頁面中使用<%...%>嵌入JAVA代碼,使用頁面編寫起來十分混亂,更不利于以后的維護。因為,JSP自定義標簽可以優雅的解決這一問題。JSTL也正是SUN為些開發的一個標簽庫,接下來讓我們來編寫自己的自定義標簽。

    定義JSP自定義標簽,需要四個步驟:

    1.        編寫一個實現Tag接口的Java類(標簽處理器類),覆蓋其中的doStartTag方法,在doStartTag方法中編寫標簽的功能代碼。

    2.        編寫標簽庫描述符(tld)文件,在tld文件中對自定義標簽進行描述。

    3.        WEB應用中部署和安裝自定義標簽庫。

    4.        JSP頁面中導入和使用自定義標簽。

    在以前的JSP頁面編寫中,我們有使用過“<cc:if test=”邏輯表達方式”>”和<cc:froEach var=”變量” items=”集合、列表、數組”>。下面我們就來實現與這兩個JSP標簽類似功能的自定義JSP標簽。

    1.編寫<cc:if test=”…”>…</cc:forEach>自定義標簽:

    IfTag.java,標簽處理器:

    import javax.servlet.jsp.*;

    import javax.servlet.jsp.tagext.Tag;

     

    public class IfTag implements Tag {

        private boolean test;

        public void setTest(boolean test) {

           this.test = test;

        }  

        public int doStartTag() throws JspException {

           if(this.test)

               return Tag.EVAL_BODY_INCLUDE;

           return Tag.SKIP_BODY;

        }

        public int doEndTag() throws JspException {

           // TODO Auto-generated method stub

           return 0;

        }

        public Tag getParent() {

           // TODO Auto-generated method stub

           return null;

        }

        public void release() {

           // TODO Auto-generated method stub

        }

        public void setPageContext(PageContext arg0) {

           // TODO Auto-generated method stub

        }

        public void setParent(Tag arg0) {

           // TODO Auto-generated method stub

        }

    }

    1.        private boolean test;”,這個成員名稱必須與JSP中自定義標簽的屬性名稱相同,JSP引擎會通過“setTest”方法,將屬性值傳遞過來。

    2.        doStartTag()”當自定義標簽開始被執行時,JSP引擎會調此方法。在此方法中可以“Tag.EVAL_BODY_INCLUDE”告訴JSP引擎繼續向下執行標簽體中的內容,如果返回“Tag.SKIP_BODYJSP引擎將不執行標簽體中的內容。

    3.        doEndTag()”當標簽體被執行完成后,會調用些方法。

    4.        getParent()”返回父標簽。

    5.        release()”,當標簽處理器被銷毀前會調用此方法,可以在此方法中釋放。但這個處理器被JSP引擎實例化后,一般不會被釋放而是保存在內存中,留以后用。服務器被關閉時,會被釋放。

    6.        setPageContext(PageContext arg0)”,JSP引擎將JSP頁面的運行環境,通過此方法傳遞給自定義標簽處理器。

    7.        setParent(Tag arg0)”,如果標簽有父標簽時,JSP引擎會將父標簽對象傳遞進來。

     

    MyEl.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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">

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

        <short-name>SimpleTagLibrary</short-name>

        <uri>/SimpleTagLibrary</uri>

       

        <tag>

           <name>myIf</name>

           <tag-class>cn.itcast.cc.jsptag.IfTag</tag-class>

           <body-content>JSP</body-content>

           <attribute>

               <name>test</name>

               <required>true</required>

               <rtexprvalue>true</rtexprvalue>

           </attribute>

        </tag>

    </taglib>

    1.        tld文件在工程中的存放位置,與web.xml存位置相同。

    2.        <uri>”設置tld描述文件的URIURI用于在JSP頁面中引入此tld文件。

    3.        <tag>”定義一個自定義標簽。

    4.        <name>”自定義標簽名。

    5.        <tag-class>”自定義標簽處理器類,就是上邊編寫的類。

    6.        <body-content>”自定義標簽的標簽體內容。(也可以設置為“empty”等)

    7.        <attribute>”為自定義標簽添加一個屬性。

    8.        <name>”自定義標簽屬性名。

    9.        <required>true為必須指定此屬性,false此屬性可為空。

    10.     <rtexprvalue>”設置屬性為靜態的或是動態的。如果為false即靜態的,靜態的屬性值JSP引擎會將它自動轉換(必須是java8種基本數據類型),比如<cc:MyIf test=”122”>JSP引擎會自動將“123”轉換為整數型,所以處理器的類成員可以定義為int型。如果為true即動態的,如果設置為將類型設置為Object可以接收任意數據類型的屬性。

     

    Index.jsp,在JSP頁面中引入自定義標簽,并調用自定義標簽:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

    <%@taglib prefix="cc" uri="/SimpleTagLibrary" %>

    <html>

      <head>

      </head>

     

      <body>

        <cc:myIf test="${2>1}">

           自定義邏輯判斷標簽!

        </cc:myIf>

      </body>

    </html>

     

    2.編寫<cc:foEach var=”temp” items=”list”>…</cc:forEach>自定義標簽:

    forEahTag.java,繼承自SimpleTagSupport,這個簡單簡化了Tag接口的操作。

    import java.io.IOException;

    import java.util.*;

    import javax.servlet.jsp.JspException;

    import javax.servlet.jsp.tagext.SimpleTagSupport;

     

    public class forEahTag extends SimpleTagSupport {

     

        // 記錄 items="xxx" 中的list對象

        private List items;

        // 記錄 var="xxx"中的變量名稱

        private String var;

     

        public void setItems(List items) {

           this.items = items;

        }

     

        public void setVar(String var) {

           this.var = var;

        }

        // SimpleTagSupport簡化了Tag接口的操作,在此只需要覆蓋doTag方法即可實現forEach。

        @Override

        public void doTag() throws JspException, IOException {

           Iterator iter = this.items.iterator();

           while (iter.hasNext()) {

               // 將單個對象設置到Context域中,在JSP頁面中可以使用${var}獲取對象。

               this.getJspContext()

                      .setAttribute(this.var, iter.next());

               // 調用執行標簽體,需要一個輸出流參數,

               // 設置為nullJSP引擎自動將其替換為this.getJspContext().getOut()

               this.getJspBody().invoke(null);

           }

        }

    }

     

    this.getJspBody()”返回JspFragment對象,JspFragment代表一個標簽體。JspFragment中不能包含JSP腳本元素。JspFragment.invoke就是調用標簽體。如果不調用此方法,就是忽略標簽體。

    forEach也可以使用實現TagSupport接口實現,當標簽體被調用時,首先會調用“doStartTag”方法(只會調用一次),可以在這個方法里先輸出第一個成員。然后執行標簽體,最后調用“doAfterBody”方法,它是重點。在這個方法里再輸出下一個成員然后判斷是不是到了list尾,如果到了list結尾則返回IterationTag. SKIP_BODY;。如果沒有到list結尾則返回IterationTag. EVAL_BODY_AGAIN;,繼續重復執行標簽體,實現對list的遍歷!

    MyEl.tld,添加如下內容:

        <tag>

           <name>myForEach</name>

           <tag-class>cn.itcast.cc.jsptag.forEahTag</tag-class>

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

           <attribute>

               <name>var</name>

               <required>true</required>

               <rtexprvalue>true</rtexprvalue>

           </attribute>

           <attribute>

               <name>items</name>

               <required>true</required>

               <rtexprvalue>true</rtexprvalue>

           </attribute>

        </tag>

             <body-content>scriptless</body-content>”指定標簽體內為非腳本代碼。

     

    Index.jsp添加如下內容:

    <%

           List list = new ArrayList();

           list.add("");

           list.add("");

           list.add("");

           this.getServletContext().setAttribute("list",list);

         %>

        <cc:myForEach items="${list}" var="temp">

           ${temp }

        </cc:myForEach>

             JSP頁面插入的代碼,是向List對象中插入成員,然后添加到ServletContext域中,${list}ServletContext域中獲取list對象。

     

             3.JSP自定義標簽高級部分:

    修改標簽內容的標簽<cc:htmlFilter><cc:readFile>兩個標簽配合使用。

    ReadFileTag.java

    public class ReadFileTag extends SimpleTagSupport {

        // 記錄文件路徑

        private String src;

          

        public void setSrc(String src) {

           this.src = src;

        }

     

        @Override

        public void doTag() throws JspException, IOException {

           // 獲取到文件的全路徑

           PageContext pc = (PageContext) this.getJspContext();

           ServletContext sc = pc.getServletContext();

           String file = sc.getRealPath(src);

           // 使用字符緩沖流讀取文件

           BufferedReader reader = new BufferedReader(new FileReader(file));

           String line = null;

           while((line = reader.readLine()) != null){

               // 寫到輸出流

               this.getJspContext().getOut().write(line + "\r\n");

           }     

        }

    }

             注意代碼中的寫到輸出流,這個輸出流是父標簽傳遞進來的輸出流。

     

    HtmlFilter.java

    public class HtmlFilter extends SimpleTagSupport {

     

        @Override

        public void doTag() throws JspException, IOException {

           // 調用子標簽,并將輸出流傳遞進去。

           CharArrayWriter caw = new CharArrayWriter(); 

           this.getJspBody().invoke(caw);

           //這里之所以要寫義一個輸出流,是為了實現Html字符的轉換

           this.getJspContext().getOut().write(filter(caw.toString()));

           System.out.println(caw.toString());

        }

       

        // Html字符轉換

        public static String filter(String message) {

     

            if (message == null)

                return (null);

     

            char content[] = new char[message.length()];

            message.getChars(0, message.length(), content, 0);

            StringBuffer result = new StringBuffer(content.length + 50);

            for (int i = 0; i < content.length; i++) {

                switch (content[i]) {

                case '<':

                    result.append("&lt;");

                    break;

                case '>':

                    result.append("&gt;");

                    break;

                case '&':

                    result.append("&amp;");

                    break;

                case '"':

                    result.append("&quot;");

                    break;

                default:

                    result.append(content[i]);

                }

            }

            return (result.toString());

        }

    }

             調用標簽體時,之所以傳遞一個自定義的輸出流。是因為,使用這個輸出流,獲取讀到的html文件的內容。然后將流中的html字符轉換后,再輸出到JSP頁面。

             二、JSTL標簽

             1.jstl標簽分為:

             核心標簽庫

    國際化標簽

    數據庫標簽

    XML標簽

    JSTL函數

             因為在JSP頁面中最好不要訪問數據庫和XML文件,這樣太不安全了而且程序邏輯混亂,所以就沒有講解這方面的使用。

     

             2.jstl常用的標簽:

             (1).<c:out>標簽:用于輸出一段文本內容到pageContext對象當前保存的“out”對象中。

             (2). <c:set>標簽:用于設置各種Web域中的屬性,或者設置Web域中的java.util.Map類型的屬性對象或JavaBean類型的屬性對象的屬性。

             (3). <c:remove>標簽:用于刪除各種Web域中的屬性。

             (4). <c:catch>標簽:用于捕獲嵌套在標簽體中的內容拋出的異常。

             (5). <c:if test=“”>標簽:可以構造簡單的“if-then”結構的條件表達式。

             (6). <c:choose>標簽:用于指定多個條件選擇的組合邊界,它必須與<c:when><c:otherwise>標簽一起使用。

             (7). <c:forEach>標簽:用于對一個集合對象中的元素進行循環迭代操作,或者按指定的次數重復迭代執行標簽體中的內容。

             (8). <c:param>標簽:它可以嵌套在<c:import><c:url><c:redirect>標簽內,為這些標簽所使用的URL地址附加參數。此標簽自動進行URL編碼。

             (9). <c:url>標簽:用于在JSP頁面中構造一個URL地址,其主要目的是實現URL重寫。還記得URL重寫是什么嗎?當session被禁用時,URL重寫就是為解決這一問題的!

             (10). <c:redirect>標簽:用于將當前的訪問請求轉發或重定向到其他資源。

          

             OK,上面是常用的標簽,使用方法去查手冊吧!東西太多了。老方今天特別提到一個標簽,是佟老師特別指出的。它在Structs中使用較多——C:check permission。

     

             比如,一個管理頁面,有好多管理選項。但管理選項需要根據用戶的權限進行顯示,此時自定義一個檢查標簽,將User做為參數傳遞給標簽處理器。標簽處理器查看User的權限,然后確定是否執行標簽體。(標簽體中的內容為顯示相應的管理選項)

     

             OK,明天就要老方就開始編寫一個將JavaSeb基礎部分的所有內容融會到一起的WEB應用用例。估計使用1天多點的時間。然后同學們有近兩天的個人實現時間。大家對此都十分期待!終于應用這段時間所學的知識,寫個像樣的東西出來。

     

             加油!


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 好吊妞788免费视频播放| 午夜影院免费观看| 欧洲美熟女乱又伦免费视频| 亚洲天堂一区在线| 免费国产作爱视频网站| 亚洲精品无码高潮喷水A片软| 色窝窝免费一区二区三区 | 免费亚洲视频在线观看| 国产精品亚洲综合| 亚洲精品国产高清嫩草影院| 久久一区二区免费播放| 国产成人亚洲综合色影视| 99久久久国产精品免费蜜臀| 亚洲乱码无限2021芒果| 免费看美女被靠到爽| 欧洲美女大片免费播放器视频| 久久久久亚洲av成人无码电影| a级片免费在线播放| 亚洲天堂一区二区三区四区| 日本免费一二区在线电影 | a毛片免费在线观看| 精品亚洲国产成AV人片传媒| 99久久99这里只有免费费精品| 亚洲午夜精品久久久久久app | 国产男女猛烈无遮挡免费网站| 黄页网址在线免费观看 | 亚洲国产情侣一区二区三区| 在线观看免费毛片| a毛片成人免费全部播放| 亚洲制服中文字幕第一区| 在线视频免费观看高清| 精品国产_亚洲人成在线| 亚洲国产精品乱码一区二区| 久久不见久久见免费影院| 一级做a爰片久久毛片免费看| 亚洲黄色在线观看网站| 国产福利免费在线观看| 97公开免费视频| 麻豆一区二区三区蜜桃免费| 亚洲精品高清视频| 国产男女猛烈无遮挡免费视频|