国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JSP自定義標(biāo)簽就是如此簡單

codercao / 3091人閱讀

摘要:傳統(tǒng)標(biāo)簽是這樣子的將標(biāo)簽體的內(nèi)容通過注入到對象中。現(xiàn)在我們使用標(biāo)簽來進(jìn)行防盜鏈模擬下場景頁面是海賊王資源,頁面提示非法盜鏈,是我的首頁。

為什么要用到簡單標(biāo)簽?

上一篇博客中我已經(jīng)講解了傳統(tǒng)標(biāo)簽,想要開發(fā)自定義標(biāo)簽,大多數(shù)情況下都要重寫doStartTag(),doAfterBody()和doEndTag()方法,并且還要知道SKIP_BODY,EVAL_BODY等等的變量代表著什么,在什么方法中使用。這樣實(shí)在是太麻煩了!

因此,為了簡化標(biāo)簽開發(fā)的復(fù)雜度,在JSP 2.0中定義了一個更為簡單、便于編寫和調(diào)用的SimpleTag接口來實(shí)現(xiàn)標(biāo)簽的功能。

一般來說,實(shí)現(xiàn)了SimpeTag接口的標(biāo)簽稱之為簡單標(biāo)簽

SimpleTag接口

首先我們來看一下它的源碼吧

    public interface SimpleTag extends JspTag {
        void doTag() throws JspException, IOException;
    
        void setParent(JspTag var1);
    
        JspTag getParent();
    
        void setJspContext(JspContext var1);
    
        void setJspBody(JspFragment var1);
    }

setParent()和getParent()方法就不多說了,我們來看一下剩下的3個方法

        void doTag() throws JspException, IOException;

        void setJspContext(JspContext var1);
    
        void setJspBody(JspFragment var1);

明顯地:

doTag()就是我們要寫代碼處理邏輯地方

setJspContext(JspContext var1)是將PageContext對象傳遞給標(biāo)簽處理器類(PageContext是JspContext的子類)

setJspBody(JspFragment var1)把代表標(biāo)簽體的JspFragment對象傳遞給標(biāo)簽處理器對象

快速入門

一般地,我們做開發(fā)都是繼承SimpleTagSupport類(該類實(shí)現(xiàn)了SimpleTag)來編寫自定義標(biāo)簽

下面我們就來個快速入門吧

目標(biāo):傳入字符串格式就可以顯示想要的格式日期,對比之前傳統(tǒng)標(biāo)簽的,看有什么不同之處

標(biāo)簽處理器類:

    public class Demo1 extends SimpleTagSupport {
    
    
        String format = null;
    
        @Override
        public void doTag() throws JspException, IOException {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
    
            this.getJspContext().getOut().write(simpleDateFormat.format(new Date()));
        }
    
        public String getFormat() {
            return format;
        }
    
        public void setFormat(String format) {
            this.format = format;
        }
    }

tld文件:

   
        formatDate
        tag.Demo1
        tagdependent
        
            format
            true
            true
        
    

效果:

簡單標(biāo)簽的好處就是不用去理會doStartTag、doEndTag、SKIP_BODY以及一系列的方法和屬性!

簡單標(biāo)簽一個doTag()方法走天下!

SimpleTagSupport類的執(zhí)行順序:

①WEB容器調(diào)用標(biāo)簽處理器對象的setJspContext方法,將代表JSP頁面的pageContext對象傳遞給標(biāo)簽處理器對象

②WEB容器調(diào)用標(biāo)簽處理器對象的setParent方法,將父標(biāo)簽處理器對象傳遞給這個標(biāo)簽處理器對象。【注意,只有在標(biāo)簽存在父標(biāo)簽的情況下,WEB容器才會調(diào)用這個方法】

③如果調(diào)用標(biāo)簽時(shí)設(shè)置了屬性,容器將調(diào)用每個屬性對應(yīng)的setter方法把屬性值傳遞給標(biāo)簽處理器對象。如果標(biāo)簽的屬性值是EL表達(dá)式或腳本表達(dá)式,則WEB容器首先計(jì)算表達(dá)式的值,然后把值傳遞給標(biāo)簽處理器對象。

④如果簡單標(biāo)簽有標(biāo)簽體,容器將調(diào)用setJspBody方法把代表標(biāo)簽體的JspFragment對象傳遞進(jìn)來

⑤執(zhí)行標(biāo)簽時(shí):容器調(diào)用標(biāo)簽處理器的doTag()方法,開發(fā)人員在方法體內(nèi)通過操作JspFragment對象,就可以實(shí)現(xiàn)是否執(zhí)行、迭代、修改標(biāo)簽體的目的。

深入簡單標(biāo)簽

在我們講解傳統(tǒng)標(biāo)簽的時(shí)候,配合著SKIP_BODY、SKIP_PAGE等變量可以實(shí)現(xiàn)如下的功能:

控制jsp頁面某一部分內(nèi)容(標(biāo)簽體)是否執(zhí)行

控制整個jsp頁面是否執(zhí)行

控制jsp頁面內(nèi)容重復(fù)執(zhí)行

修改jsp頁面內(nèi)容輸出

簡單標(biāo)簽可沒有這些變量呀,那它怎么才能實(shí)現(xiàn)上面那些功能呢?

在doTag方法中可以拋出javax.servlet.jsp.SkipPageException異常,用于通知WEB容器不再執(zhí)行JSP頁面中位于結(jié)束標(biāo)記后面的內(nèi)容,這等效于在傳統(tǒng)標(biāo)簽的doEndTag方法中返回Tag.SKIP_PAGE常量的情況,我們來測試一下,在上面例子的代碼中添加

    throw new SkipPageException();

效果:

至于其他的功能下面會講到

帶標(biāo)簽體的簡單標(biāo)簽

SimpleTagSupport也可以帶標(biāo)簽體,但是處理方法和傳統(tǒng)標(biāo)簽完全不同

傳統(tǒng)標(biāo)簽是這樣子的:將標(biāo)簽體的內(nèi)容通過setBodyContent()注入到BodyContent對象中。

簡單標(biāo)簽是這樣子的:通過JspFragment對象實(shí)現(xiàn)!

我們來看一下JspFragment對象的源碼吧


    public abstract class JspFragment {
        public JspFragment() {
        }
    
        public abstract void invoke(Writer var1) throws JspException, IOException;
    
        public abstract JspContext getJspContext();
    }

JspFragment對象十分簡單,重要的只有invoke(Writer var1)方法(獲取JspContext對象并不重要,在標(biāo)簽描述器上就可以獲取到了)

public abstract void invoke(java.io.Writer out) :

用于執(zhí)行JspFragment對象所代表的JSP代碼片段

參數(shù)out用于指定將JspFragment對象的執(zhí)行結(jié)果寫入到哪個輸出流對象中,如果傳遞給參數(shù)out的值為null,則將執(zhí)行結(jié)果寫入到JspContext.getOut()方法返回的輸出流對象中。(簡而言之,可以理解為寫給瀏覽器)

下面是標(biāo)簽處理器類的代碼

    public class Demo1 extends SimpleTagSupport {
        @Override
        public void doTag() throws JspException, IOException {
    
            //得到代表標(biāo)簽體的對象
            JspFragment jspFragment = getJspBody();
    
            //invoke方法接收的是一個Writer,如果為null,就代表著JspWriter(),將標(biāo)簽體的數(shù)據(jù)寫給瀏覽器!
            jspFragment.invoke(null);
            
        }
    }

效果:

既然標(biāo)簽體的內(nèi)容是通過JspFragment對象的invoke()方法寫給瀏覽器的,那么那么那么,我只要控制好invoke()方法,我想干什么就干什么!

也就是說:

不調(diào)用invoke()方法,標(biāo)簽體內(nèi)容就不會輸出到瀏覽器上

重復(fù)調(diào)用invoke()方法,標(biāo)簽體內(nèi)容就會被重復(fù)執(zhí)行

若想在標(biāo)簽處理器中修改標(biāo)簽體內(nèi)容,只需在調(diào)用invoke方法時(shí)指定一個可取出結(jié)果數(shù)據(jù)的輸出流對象(例如StringWriter),讓標(biāo)簽體的執(zhí)行結(jié)果輸出到該輸出流對象中,然后從該輸出流對象中取出數(shù)據(jù)進(jìn)行修改后再輸出到目標(biāo)設(shè)備,即可達(dá)到修改標(biāo)簽體的目的

來來來,我們來試驗(yàn)一下:

不調(diào)用invoke()方法

    public void doTag() throws JspException, IOException {

        //得到代表標(biāo)簽體的對象
        JspFragment jspFragment = getJspBody();
        
        //jspFragment.invoke(null);

    }

- **標(biāo)簽體的內(nèi)容沒有輸出**
![](http://i.imgur.com/rgEAjZG.png) 

- **調(diào)用兩次invoke()方法**

```java

    public void doTag() throws JspException, IOException {

        //得到代表標(biāo)簽體的對象
        JspFragment jspFragment = getJspBody();

        jspFragment.invoke(null);
        jspFragment.invoke(null);

    }


```
- **標(biāo)簽體的內(nèi)容被輸出了兩次**!
![](http://i.imgur.com/UH8VAhw.png)
- **invoke()方法指定別的輸出流(StringWriter),將標(biāo)簽體的內(nèi)容寫到流對象中,再通過流對象把數(shù)據(jù)取出來,達(dá)到修改的目的。**


```java

        //得到代表標(biāo)簽體的對象
        JspFragment jspFragment = getJspBody();

        //創(chuàng)建可以存儲字符串的Writer對象
        StringWriter stringWriter = new StringWriter();

        //invoke()方法把標(biāo)簽體的數(shù)據(jù)都寫給流對象中
        jspFragment.invoke(stringWriter);

        //把流對象的數(shù)據(jù)取出來,流對象的數(shù)據(jù)就是標(biāo)簽體的內(nèi)容
        String value = stringWriter.toString();

        //將數(shù)據(jù)改成是大寫的,寫到瀏覽器中
        getJspContext().getOut().write(value.toUpperCase());

```

- **標(biāo)簽體的內(nèi)容被改成了大寫!**

![](http://i.imgur.com/HpbrbKR.png)





我們可以發(fā)現(xiàn),傳統(tǒng)標(biāo)簽?zāi)芡瓿傻墓δ埽唵螛?biāo)簽都可以完成,并且更為簡單!

自定義標(biāo)簽的應(yīng)用

既然我們學(xué)了簡單標(biāo)簽,我們就用簡單標(biāo)簽來做開發(fā)吧!

防盜鏈

在講解request對象的時(shí)候,我們講解過怎么實(shí)現(xiàn)防盜鏈的功能。現(xiàn)在我們使用標(biāo)簽來進(jìn)行防盜鏈

模擬下場景:1.jsp頁面是海賊王資源,2.jsp頁面提示非法盜鏈,index1.jsp是我的首頁。別人想要看我的海賊王資源,就必須通過我的首頁點(diǎn)進(jìn)去看,否則就是非法盜鏈!

標(biāo)簽處理器的代碼

    @Override
    public void doTag() throws JspException, IOException {

        //如果想要做成更加靈活的,就把站點(diǎn)設(shè)置和資源設(shè)置成標(biāo)簽屬性傳遞進(jìn)來!

        //等會我們要獲取得到request對象,需要使用到JspContext的子類PageContext
        PageContext pageContext = (PageContext) this.getJspContext();

        //獲取request對象
        HttpServletRequest httpServletRequest = (HttpServletRequest) pageContext.getRequest();

        //獲取到referer
        String referer = httpServletRequest.getHeader("Referer");

        //獲取到response對象,等會如果是非法盜鏈,就重定向別的頁面上
        HttpServletResponse httpServletResponse = (HttpServletResponse) pageContext.getResponse();
        
        //非法盜鏈!
        if (referer == null || !referer.startsWith("http://localhost:8080/zhongfucheng")) {

            //2.jsp提示了非法盜鏈!
            httpServletResponse.sendRedirect("/zhongfucheng/2.jsp");

            //不執(zhí)行頁面下面的內(nèi)容了,保護(hù)頁面
            throw new SkipPageException();
        }
    }

1.jsp代碼:

    
    
    
        
    
    
    
    海賊王最新資源
    
    
    

index1.jsp代碼

    

這是首頁!

海賊王最新資源

2.jsp代碼

    
    你是非法盜鏈的!!!!!!
    

第一次我是直接訪問1.jsp,Referer是為空的,所以是非法盜鏈。第二次我是通過從首頁點(diǎn)進(jìn)去看的,所以可以訪問1.jsp。效果圖:

if標(biāo)簽

在JSTL中,我們已經(jīng)使用過了標(biāo)簽了,現(xiàn)在我們學(xué)習(xí)了自定義標(biāo)簽,可以開發(fā)類似于JSTL的if標(biāo)簽了!

既然是if標(biāo)簽,那么就需要編寫帶屬性和帶標(biāo)簽體的標(biāo)簽(需要判斷是true還是false呀!,通過判斷是否為真值來決定是否執(zhí)行標(biāo)簽體的內(nèi)容)

標(biāo)簽處理器代碼

    public class Demo1 extends SimpleTagSupport {
        
        //定義一個Boolean類型的變量
        boolean test ;
    
        @Override
        public void doTag() throws JspException, IOException {
    
            //獲取到代表標(biāo)簽體內(nèi)容的對象
            JspFragment jspFragment = this.getJspBody();
    
            //如果為真值才執(zhí)行標(biāo)簽體的內(nèi)容
            if (test == true) {
                jspFragment.invoke(null);
            }
        }
    
        public boolean isTest() {
            return test;
        }
    
        public void setTest(boolean test) {
            this.test = test;
        }
    }

tld文件的代碼

    
        if
         tag.Demo1
        scriptless
        
            test
            true
            true
        
    

本來就沒有user這個域?qū)ο髮傩裕評ser就是為null

將user改成不為null,瀏覽器就沒有輸出了

forEach標(biāo)簽

forEach標(biāo)簽最基本的功能:遍歷集合、數(shù)組

首先,我先寫一個可以遍歷List集合的標(biāo)簽,可能我們會這樣設(shè)計(jì)

public class Demo2 extends SimpleTagSupport {

    //遍歷的是List集合,于是標(biāo)簽的屬性就為List
    private List items;

    //遍歷出來的對象就用Object存著,因?yàn)槲覀儾恢繪ist集合保存的是什么元素
    private Object var;


    @Override
    public void doTag() throws JspException, IOException {

        //獲取到迭代器
        Iterator iterator = items.iterator();

        //遍歷集合
        while (iterator.hasNext()) {

            //獲取到集合的元素
            var = iterator.next();

            //.....var屬性代表的就是集合的元素,現(xiàn)在問題來了,好像在標(biāo)簽體內(nèi)無法獲取到這個對象....
            //做到這里完成不下去了....
        }
    }

    public void setItems(List items) {
        this.items = items;
    }

    public void setVar(Object var) {
        this.var = var;
    }
}

上面的思路是正常的,但是做不下去!我們換一個思路唄。上面的問題主要是在標(biāo)簽體獲取不到被遍歷出來的對象

我們這樣做:把var定義成String類型的,如果遍歷得到對象了,就設(shè)置PageContext的屬性,var為關(guān)鍵字,對象為值。在標(biāo)簽體用EL表達(dá)式搜索以var為關(guān)鍵字的對象!每遍歷出一個對象,就執(zhí)行一次標(biāo)簽體!

于是就有了以下的代碼!

public class Demo1 extends SimpleTagSupport {

    //遍歷的是List集合,定義List集合成員變量
    private List items;

    //以var為關(guān)鍵字存儲到PageContext
    private String var;



    @Override
    public void doTag() throws JspException, IOException {

        //獲取到集合的迭代器
        Iterator iterator = items.iterator();

        //獲取到代表標(biāo)簽體內(nèi)容的對象
        JspFragment jspFragment = this.getJspBody();

        //遍歷集合
        while (iterator.hasNext()) {
            Object o = iterator.next();

            //把遍歷出來的對象存儲到page范圍中,關(guān)鍵字為標(biāo)簽的屬性var(在標(biāo)簽體中使用EL表達(dá)式${var},就能夠獲取到集合的對象了!)
            this.getJspContext().setAttribute(var, o);

            //每設(shè)置了一個屬性,我就執(zhí)行標(biāo)簽體
            jspFragment.invoke(null);
        }
    }

    public void setItems(List items) {
        this.items = items;
    }

    public void setVar(String var) {
        this.var = var;
    }
}

tld文件如下

    
        forEach
        tag.Demo1
        scriptless
        
            var
            true
            
            false
        

        
            items
            true
            true
        
    

測試的jsp代碼如下

    <%
        List list = new ArrayList();
        list.add("zhongfucneng");
        list.add("1");
        list.add("2");
        list.add("3");
    
        request.setAttribute("list",list);
    %>
    
    
        ${str}
    
    

效果:

上面寫的僅僅能夠遍歷List集合,做一個通用的forEach標(biāo)簽麻煩的是在:不知道傳進(jìn)來的是什么類型的數(shù)組、什么類型集合!,需要逐一去判斷

我們的實(shí)現(xiàn)思路就是將所有的集合或數(shù)組都轉(zhuǎn)成是Collection類型的!

我們來嘗試著寫一下

        //如果items是Collection類型的,就強(qiáng)轉(zhuǎn)為Colletion
        if (items instanceof Collection) {
            collection = (Collection) items;
        }

        //如果itmes是Map類型的,那么就強(qiáng)轉(zhuǎn)為Map,再獲取到,這個是Set集合的!
        if (items instanceof Map) {
            Map map = (Map) items;
            collection = (Collection) map.entrySet();
        }
        
        //對象數(shù)組
        if (items instanceof Object[]) {
            Object[] objects = (Object[]) items;
            collection = Arrays.asList(objects);
        }
        
        //int[],Byte[],char[]等八大基本數(shù)據(jù)類型.....
        

還有int[],byte[],char[]等八大基本數(shù)據(jù)類型,這八大基本數(shù)據(jù)類型就不能用Arrays.asList()把引用傳進(jìn)去了。因?yàn)镴DK5以后會把引用自動裝箱成Interger[]、Byte[]等等,而不是獲取到數(shù)組的元素?cái)?shù)據(jù)。

測試代碼如下:

    public static void main(String[] args) {

        int[] ints = new int[]{1, 2, 3};
        Object[] objects = new Object[]{"1", "2", "3"};

        if (objects instanceof Object[]) {
            Collection collection = Arrays.asList(objects);
            System.out.println(collection);
        }
        if (ints instanceof int[]) {

            Collection collection1 = Arrays.asList(ints);
            System.out.println(collection1);
        }
    }

效果:

對于八大基本類型數(shù)據(jù)我們就可以這樣干


        if (items instanceof int[]) {
            int[] ints = (int[]) items;
            collection = new ArrayList();
            for (int anInt : ints) {
                collection.add(anInt);
            }
            
        }
        //......這里還要寫7個

JSTL的forEach標(biāo)簽類似就是這樣干的

由于JDK5的新特性,我們又有另外的解決方案,Class對象能夠判斷是否為數(shù)組類,reflect反射包下Array類

其實(shí),無論Map集合、還是任何類型的數(shù)組、都可以使用Colletion進(jìn)行遍歷!。

如果是八大基本數(shù)據(jù)類型的數(shù)組,我們就使用反射來進(jìn)行構(gòu)建出Collection集合。

標(biāo)簽處理器的代碼

public class Demo1 extends SimpleTagSupport {

    //遍歷的是未知的集合或數(shù)組,定義成Object
    private Object items;

    //每次被遍歷的對象存儲關(guān)鍵字
    private String var;

    //Colletion
    private Collection collection;

    //在WEB容器設(shè)置標(biāo)簽的屬性的時(shí)候,判斷是什么類型的數(shù)組和集合
    public void setItems(Object items) {
        this.items = items;

        //如果items是Collection類型的,就強(qiáng)轉(zhuǎn)為Colletion
        if (items instanceof Collection) {
            collection = (Collection) items;
        }

        //如果itmes是Map類型的,那么就強(qiáng)轉(zhuǎn)為Map,再獲取到,這個是Set集合的!
        if (items instanceof Map) {
            Map map = (Map) items;
            collection = (Collection) map.entrySet();
        }

        //可以這樣解決,Class對象判斷是否是一個數(shù)組類
        if (items.getClass().isArray()) {

            //創(chuàng)建Collection集合添加數(shù)組的元素!
            collection = new ArrayList();

            //再利用reflect包下的Array類獲取到該數(shù)組類的長度
            int len = Array.getLength(items);

            //遍歷并添加到集合中
            for (int i = 0; i < len; i++) {
                collection.add(Array.get(items, i));
            }
        }
    }

    public void setVar(String var) {
        this.var = var;
    }

   @Override
    public void doTag() throws JspException, IOException {

        //獲取到代表標(biāo)簽體內(nèi)容的對象
        JspFragment jspFragment = this.getJspBody();
        Iterator iterator = collection.iterator();


        //遍歷集合
        while (iterator.hasNext()) {
            Object o = iterator.next();

            //把遍歷出來的對象存儲到page范圍中(在標(biāo)簽體中使用EL表達(dá)式${var},就能夠獲取到集合的對象了!)
            this.getJspContext().setAttribute(var, o);

            jspFragment.invoke(null);
        }
    }
}

tld文件和上面是一樣的,下面是測試代碼


<%
    /*list集合*/
    List list = new ArrayList();
    list.add("zhongfucneng");
    list.add("1");
    list.add("2");
    list.add("3");
    request.setAttribute("list",list);

    /*基本數(shù)據(jù)類型數(shù)組*/
    int[] ints = new int[]{1, 2, 3, 4, 5};
    request.setAttribute("ints", ints);

    /*對象數(shù)組*/
    Object[] objects = new Object[]{2, 3, 4, 5, 6};
    request.setAttribute("objects", objects);

    /*map集合*/
    Map map = new HashMap();
    map.put("aa", "aa");
    map.put("bb", "bb");
    map.put("cc", "cc");
    request.setAttribute("map",map);
%>

    List集合:
    
        ${str}
    
    
    

基本數(shù)據(jù)類型數(shù)組: ${i}

對象數(shù)組: ${o}

map集合: ${me.key} = ${me.value}

效果:

HTML轉(zhuǎn)義標(biāo)簽

要開發(fā)這個標(biāo)簽就很簡單了,只要獲取到標(biāo)簽體的內(nèi)容,再通過經(jīng)過方法轉(zhuǎn)義下標(biāo)簽體內(nèi)容,輸出給瀏覽器即可

標(biāo)簽處理器代碼:

public class Demo1 extends SimpleTagSupport {



   @Override
    public void doTag() throws JspException, IOException {

       //獲取到標(biāo)簽體的內(nèi)容再修改
       StringWriter stringWriter = new StringWriter();
       JspFragment jspFragment = this.getJspBody();
       jspFragment.invoke(stringWriter);
       String content = stringWriter.toString();

       //經(jīng)過filter()轉(zhuǎn)義,該方法在Tomcat可以找到
       content = filter(content);

       //再把轉(zhuǎn)義后的內(nèi)容輸出給瀏覽器
       this.getJspContext().getOut().write(content);


    }

    private 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("<");
                    break;
                case ">":
                    result.append(">");
                    break;
                case "&":
                    result.append("&");
                    break;
                case """:
                    result.append(""");
                    break;
                default:
                    result.append(content[i]);
            }
        }

        return (result.toString());
    }
}

測試代碼

    
    你好啊 
    
    
你好啊

效果:

if else標(biāo)簽

在JSTL中并沒有if else的標(biāo)簽,JSTL給予我們的是choose,when,otherwise標(biāo)簽,現(xiàn)在我們模仿choose,when,otherwise開發(fā)標(biāo)簽

思路:when標(biāo)簽有個test屬性,但otherwise怎么判斷標(biāo)簽體是執(zhí)行還是不執(zhí)行呢?這時(shí)就需要choose標(biāo)簽的支持了!choose標(biāo)簽?zāi)J(rèn)定義一個Boolean值為false,。當(dāng)when標(biāo)簽體被執(zhí)行了,就把Boolean值變成true,只要Boolean值為false就執(zhí)行otherwise標(biāo)簽體的內(nèi)容。

看程序就容易理解上面那句話了:

choose標(biāo)簽處理器

    public class Choose extends SimpleTagSupport {
    
        private boolean flag;
    
        @Override
        public void doTag() throws JspException, IOException {
    
            this.getJspBody().invoke(null);
        }
    
        public boolean isFlag() {
            return flag;
        }
    
        public void setFlag(boolean flag) {
            this.flag = flag;
        }
    }

When標(biāo)簽處理器

    public class When extends SimpleTagSupport {
    
        private boolean test ;
    
        @Override
        public void doTag() throws JspException, IOException {
    
    
            Choose choose = (Choose) this.getParent();
    
            //如果test為true和flag為false,那么執(zhí)行該標(biāo)簽體
            if (test == true && choose.isFlag() == false) {
    
                this.getJspBody().invoke(null);
    
                //修改父標(biāo)簽的flag
                choose.setFlag(true);
            }
    
        }
        public void setTest(boolean test) {
            this.test = test;
        }
    }

OtherWise標(biāo)簽處理器


    public class OtherWise extends SimpleTagSupport {
    
    
        @Override
        public void doTag() throws JspException, IOException {
    
    
            Choose choose = (Choose) this.getParent();
    
            //如果父標(biāo)簽的flag為false,就執(zhí)行標(biāo)簽體(如果when標(biāo)簽沒執(zhí)行,flag值就不會被修改!when標(biāo)簽沒執(zhí)行,就應(yīng)該執(zhí)行otherwise標(biāo)簽!)
            if (choose.isFlag() == false) {
                getJspBody().invoke(null);
    
                //改父標(biāo)簽的flag為false
                choose.setFlag(true);
    
            }
        }
    }

測試代碼:

    
        
            user為空
        
    
        
            user不為空
        
    
    

效果:

DynamicAttribute接口

此接口的主要功能是用于完成動態(tài)屬性的設(shè)置!前面我們講解屬性標(biāo)簽的時(shí)候,屬性都是寫多少個,用多少個的。現(xiàn)在如果我希望屬性可以動態(tài)的增加,只需要在標(biāo)簽處理器類中實(shí)現(xiàn)DynamicAttribute接口即可!

現(xiàn)在我要開發(fā)一個動態(tài)加法的標(biāo)簽

標(biāo)簽處理器

    public class Demo1 extends SimpleTagSupport implements DynamicAttributes {
    
        //既然有動態(tài)屬性和動態(tài)的值,那么我們就用一個Map集合存儲(1-1對應(yīng)的關(guān)系),做的加法運(yùn)算,值為Double類型的。
        Map map = new HashMap<>();
    
        @Override
        public void doTag() throws JspException, IOException {
    
            //定義一個sum變量用于計(jì)算總值
            double sum = 0.0;
    
            //獲取到Map集合的數(shù)據(jù)
            Iterator iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
    
                sum += entry.getValue();
            }
    
            //向?yàn)g覽器輸出總和是多少
            this.getJspContext().getOut().write(String.valueOf(sum));
        }
    
    
        //對于這個要實(shí)現(xiàn)的方法,我們只要關(guān)注第2個參數(shù)和第3個參數(shù)即可
        //第二個參數(shù)表示的是動態(tài)屬性的名稱,第三個參數(shù)表示的是動態(tài)屬性的值
        @Override
        public void setDynamicAttribute(String s, String localName, Object value) throws JspException {
    
            //將動態(tài)屬性的名字和值加到Map集合中
            map.put(localName, Double.valueOf(Float.valueOf(value.toString())));
        }
    }

tld文件,注意要把dynamic-attribute設(shè)置為true


    
        dynamicAttribute
         tag.Demo1
         empty

        
        true
    

測試代碼

    

效果,double在運(yùn)算的時(shí)候會丟失精度的,現(xiàn)在只是測驗(yàn)下動態(tài)屬性,這里就不詳細(xì)說了!

開發(fā)自定義函數(shù)

至于怎么開發(fā)自定義函數(shù),在EL表達(dá)式的博客中有

如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),可以關(guān)注微信公眾號:Java3y

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/68478.html

相關(guān)文章

  • JSP第六篇【定義標(biāo)簽之傳統(tǒng)標(biāo)簽

    摘要:首先我們來看一下接口的源碼上面程序的執(zhí)行流程引擎遇到自定義標(biāo)簽,首先創(chuàng)建標(biāo)簽處理器類的實(shí)例對象。當(dāng)容器執(zhí)行到自定義標(biāo)簽的結(jié)束標(biāo)記時(shí),調(diào)用方法。 為什么要使用自定義標(biāo)簽? JSTL標(biāo)簽庫只提供了簡單的輸出等功能,沒有實(shí)現(xiàn)任何的HTML代碼封裝,并且某些復(fù)雜類型轉(zhuǎn)換,或者邏輯處理的時(shí)候,JSTL標(biāo)簽庫完成不了,需要自定義標(biāo)簽! 編寫自定義標(biāo)簽的步驟: 編寫一個實(shí)現(xiàn)Tag接口的Java類【...

    songze 評論0 收藏0
  • JSP面試題都在這里

    摘要:下面是我整理下來的知識點(diǎn)圖上的知識點(diǎn)都可以在我其他的文章內(nèi)找到相應(yīng)內(nèi)容。在中,尤其重要的是對象。 下面是我整理下來的JSP知識點(diǎn): showImg(https://segmentfault.com/img/remote/1460000013229216?w=4962&h=2653); 圖上的知識點(diǎn)都可以在我其他的文章內(nèi)找到相應(yīng)內(nèi)容。 JSP常見面試題 jsp靜態(tài)包含和動態(tài)包含的區(qū)別 j...

    gaosboy 評論0 收藏0
  • JSP第四篇【EL表達(dá)式介紹、獲取各類數(shù)據(jù)、11個內(nèi)置對象、執(zhí)行運(yùn)算、回顯數(shù)據(jù)、定義函數(shù)、fn方法

    什么是EL表達(dá)式? 表達(dá)式語言(Expression Language,EL),EL表達(dá)式是用${}括起來的腳本,用來更方便的讀取對象! EL表達(dá)式主要用來讀取數(shù)據(jù),進(jìn)行內(nèi)容的顯示! 為什么要使用EL表達(dá)式? 為什么要使用EL表達(dá)式,我們先來看一下沒有EL表達(dá)式是怎么樣讀取對象數(shù)據(jù)的吧! 在1.jsp中設(shè)置了Session屬性 向session設(shè)置一個屬性 在2...

    flyer_dev 評論0 收藏0
  • Java3y文章目錄導(dǎo)航

    摘要:前言由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號:Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...

    KevinYan 評論0 收藏0
  • Struts2【UI標(biāo)簽、數(shù)據(jù)回顯、資源國際化】

    摘要:值得注意的是的值是文件的全名也就是說,如果有包,就把包名寫上并且,不需要寫上后綴標(biāo)簽使用國際化的值是配置文件中配置的信息,寫上就行了登陸測試注意,已經(jīng)替換成了中文了如果文章有錯的地方歡迎指正,大家互相交流。 Struts2UI標(biāo)簽 Sturts2為了簡化我們的開發(fā),也為我們提供了UI標(biāo)簽...也就是顯示頁面的標(biāo)簽..... 但是呢,Struts2是服務(wù)端的框架,因此使用頁面的標(biāo)簽是需要...

    graf 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<