欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JSP传统标签开发

程序员文章站 2022-04-12 20:07:07
标签技术的api 标签技术的api类继承关系 标签api简单介绍 jsptag接口">jsptag接口 jsptag接口是所有自定义标签的父接口,它是jsp2.0中新定义的一个标记接口,没有任何属...

标签技术的api

标签技术的api类继承关系

JSP传统标签开发

标签api简单介绍

jsptag接口是所有自定义标签的父接口,它是jsp2.0中新定义的一个标记接口,没有任何属性和方法。jsptag接口有tag和simpletag两个直接子接口,jsp2.0以前的版本中只有tag接口,所以把实现tag接口的自定义标签也叫做传统标签,把实现simpletag接口的自定义标签叫做简单标签

tag接口

tag接口是所有传统标签的父接口,其中定义了两个重要方法(dostarttag、doendtag)方法和四个常量(eval_body_include、skip_body、eval_page、skip_page),这两个方法和四个常量的作用如下:

web容器在解释执行jsp页面的过程中,遇到自定义标签的开始标记就会去调用标签处理器的dostarttag方法,dostarttag方法执行完后可以向web容器返回常量eval_body_include或skip_body。如果dostarttag方法返回eval_body_include,web容器就会接着执行自定义标签的标签体;如果dostarttag方法返回skip_body,web容器就会忽略自定义标签的标签体,直接解释执行自定义标签的结束标记。 web容器解释执行到自定义标签的结束标记时,就会调用标签处理器的doendtag方法,doendtag方法执行完后可以向web容器返回常量eval_page或skip_page。如果doendtag方法返回常量eval_page,web容器就会接着执行jsp页面中位于结束标记后面的jsp代码;如果doendtag方法返回skip_page,web容器就会忽略jsp页面中位于结束标记后面的所有内容。
doendtag()方法的返回值——标识是不是继续执行余下的jsp。要想用标签控制余下的jsp是否执行,只需控制doendtag()方法的返回值

从dostarttag和doendtag方法的作用和返回值的作用可以看出,开发自定义标签时可以在dostarttag方法和doendtag方法体内编写合适的java程序代码来实现具体的功能,通过控制dostarttag方法和doendtag方法的返回值,还可以告诉web容器是否执行自定义标签中的标签体内容和jsp页面中位于自定义标签的结束标记后面的内容。

iterationtag接口

iterationtag接口继承了tag接口,并在tag接口的基础上增加了一个doafterbody方法和一个eval_body_again常量。实现iterationtag接口的标签除了可以完成tag接口所能完成的功能外,还能够通知web容器是否重复执行标签体内容。对于实现了iterationtag接口的自定义标签,web容器在执行完自定义标签的标签体后,将调用标签处理器的doafterbody方法,doafterbody方法可以向web容器返回常量eval_body_again或skip_body。如果doafterbody方法返回eval_body_again,web容器就会把标签体内容再重复执行一次,执行完后接着再调用doafterbody方法,如此往复,直到doafterbody方法返回常量skip_body,web容器才会开始处理标签的结束标记和调用doendtag方法。
可见,开发自定义标签时,可以通过控制doafterbody方法的返回值来告诉web容器是否重复执行标签体内容,从而达到循环处理标签体内容的效果。例如,可以通过一个实现iterationtag接口的标签来迭代输出一个集合中的所有元素,在标签体部分指定元素的输出格式。
jsp api中也提供了iterationtag接口的默认实现类tagsupport,我们在编写自定义标签的标签处理器类时,可以继承和扩展tagsupport类,这相比实现iterationtag接口将简化开发工作。

bodytag接口

bodytag接口继承了iterationtag接口,并在iterationtag接口的基础上增加了两个方法(setbodycontent、doinitbody)和一个eval_body_buffered常量。实现bodytag接口的标签除了可以完成iterationtag接口所能完成的功能,还可以对标签体内容进行修改。对于实现了bodytag接口的自定义标签,标签处理器的dostarttag方法不仅可以返回前面讲解的常量eval_body_include或skip_body,还可以返回常量eval_body_buffered。如果dostarttag方法返回eval_body_buffered,web容器就会创建一个专用于捕获标签体运行结果的bodycontent对象,然后调用标签处理器的setbodycontent方法将bodycontent对象的引用传递给标签处理器,web容器接着将标签体的执行结果写入到bodycontent对象中。在标签处理器的后续事件方法中,可以通过先前保存的bodycontent对象的引用来获取标签体的执行结果,然后调用bodycontent对象特有的方法对bodycontent对象中的内容(即标签体的执行结果)进行修改和控制其输出。
jsp api中也提供了bodytag接口的实现类bodytagsupport,我们在编写能够修改标签体内容的自定义标签的标签处理器类时,可以继承和扩展bodytagsupport类,这相比实现bodytag接口将简化开发工作。

simpletag接口

simpletag接口是jsp2.0中新增的一个标签接口。由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的,因此,sun公司为降低标签技术的学习难度,在jsp 2.0中定义了一个更为简单、便于编写和调用的simpletag接口。simpletag接口与传统标签接口最大的区别在于,simpletag接口只定义了一个用于处理标签逻辑的dotag方法,该方法在web容器执行自定义标签时调用,并且只被调用一次。那些使用传统标签接口所完成的功能,例如是否执行标签体、迭代标签体、对标签体内容进行修改等功能都可以在dotag方法中完成。
jsp api中也提供了simpletag接口的实现类simpletagsupport,我们在编写简单标签时,可以继承和扩展simpletagsupport类,这相比实现simpletag接口将简化开发工作。

传统标签接口中的各个方法可以返回的返回值说明

下图列举了tag接口、iterationtag接口和bodytag接口中的主要方法及它们分别可以返回的返回值的说明。
JSP传统标签开发

开发传统标签实现页面逻辑

开发人员在编写jsp页面时,经常还需要在页面中引入一些逻辑,例如:

控制jsp页面某一部分内容是否执行。 控制整个jsp页面是否执行。 控制jsp页面内容重复执行。 修改jsp页面内容输出。

自定义标签除了可以移除jsp页面java代码外,它也可以实现以上功能。

控制jsp页面某一部分内容是否执行 

编写一个类实现tag接口,控制dostarttag()方法的返回值,如果这个方法返回eval_body_include,则执行标签体,如果返回skip_body,则不执行标签体。
sun公司针对tag接口提供了一个默认的实现类tagsupport,tagsupport类中实现了tag接口的所有方法,因此我们可以编写一个类继承tagsupport类,然后再重写dostarttag方法。
示例代码如下:
tagdemo1.java:

public class tagdemo1 extends tagsupport {

    // 控制dostarttag()方法的返回值,即可控制标签体是否输出
    @override
    public int dostarttag() throws jspexception {

        return tag.skip_body;
    }

}

在web-inf目录下的itcast.tld文件中添加对该标签处理类的描述,如下:


    demo1
    cn.itcast.web.tag.tagdemo1
     
    jsp

在jsp页面中导入并使用自定义标签,如下:

<%@ page language="java" contenttype="text/html; charset=utf-8"
    pageencoding="utf-8"%>
<%@ taglib uri="http://www.itcast.cn" prefix="itcast" %>

aaaaaaaaaaaaaaaa

运行效果如下:
JSP传统标签开发

控制整个jsp页面是否执行

编写一个类实现tag接口,控制doendtag()方法的返回值,如果这个方法返回eval_page,则执行标签余下的jsp页面,如果返回skip_page,则不执行余下的jsp。
示例代码如下:
tagdemo2.java:

public class tagdemo2 extends tagsupport {

    @override
    public int doendtag() throws jspexception {
        // return tag.skip_page;
        return tag.eval_page;
    }

}

在web-inf目录下的itcast.tld文件中添加对该标签处理类的描述,如下:


    demo2
    cn.itcast.web.tag.tagdemo2
    
    empty

在jsp页面中导入并使用自定义标签,如下:

<%@ page language="java" contenttype="text/html; charset=utf-8"
    pageencoding="utf-8"%>
<%@ taglib uri="http://www.itcast.cn" prefix="itcast" %>

    aaaaaaaaaaaaa

运行效果如下:
JSP传统标签开发

控制jsp页面内容重复执行

编写一个类实现iterationtag接口,控制doafterbody()方法的返回值,如果这个方法返回eval_body_again, 则web服务器又执行一次标签体,依次类推,一直执行到doafterbody方法返回skip_body,则标签体才不会重复执行。
doafterbody()方法的执行时机是标签体执行之后以及结束标签执行之前。如果这个方法返回的是eval_body_again,服务器只要接收到这个常量,它这时又会把标签体再执行一次,如果把标签体执行完之后,又会调用doafterbody()方法,…依次类推,一直执行到doafterbody()方法返回skip_body,这时不会再执行标签体,就会执行标签体下面的结束标签。
示例代码如下:
tagdemo3.java:

// 控制标签体执行5次
public class tagdemo3 extends tagsupport {

    int x = 5;
    @override
    public int doafterbody() throws jspexception {
        x--;
        if(x>0) {
            return iterationtag.eval_body_again;
        } else {
            return iterationtag.skip_body;
        }

    }

    @override
    public int dostarttag() throws jspexception {
        // todo auto-generated method stub
        return tag.eval_body_include;
    }


}

在web-inf目录下的itcast.tld文件中添加对该标签处理类的描述,如下:


    demo3
    cn.itcast.web.tag.tagdemo3
    
    jsp

在jsp页面中导入并使用自定义标签,如下:

<%@ page language="java" contenttype="text/html; charset=utf-8"
    pageencoding="utf-8"%>
<%@ taglib uri="http://www.itcast.cn" prefix="itcast" %>

this is my jsp page.

运行效果如下:
JSP传统标签开发

修改jsp页面内容输出

编写一个类实现bodytag接口,控制dostarttag()方法返回eval_body_buffered,则web服务器会创建bodycontent对象捕获标签体,然后在doendtag()方法体内,得到代表标签体的bodycontent对象,从而就可以对标签体进行修改操作。
更详细的说法:如果编写的java类实现了bodytag接口,那这时可以控制开始标签对应的方法dostarttag()返回eval_body_buffered,只要返回eval_body_buffered,服务器拿到标签体之后,它会把标签体作为一个对象通过setbodycontent()方法传递给标签处理器类,接下来可以在结束标签对应的方法doendtag()方法里面拿到标签体,从而可以对标签体修改后输出。
sun公司针对bodytag接口提供了一个默认的实现类bodytagsupport,bodytagsupport类中实现了bodytag接口的所有方法,因此我们可以编写一个类继承bodytagsupport类,然后再根据需要重写dostarttag方法和doendtag()方法。
示例代码如下:
tagdemo4.java:

// 修改标签体(把标签体改为大写)
public class tagdemo4 extends bodytagsupport {

    @override
    public int dostarttag() throws jspexception {
        return bodytag.eval_body_buffered;
    }

    @override
    public int doendtag() throws jspexception {
        bodycontent bc = this.getbodycontent(); // 得到标签体
        string content = bc.getstring();
        content = content.touppercase();

        try {
            this.pagecontext.getout().write(content);
        } catch (ioexception e) {
            throw new runtimeexception(e);
        }

        // 只是修改标签体,余下的jsp还是要继续执行
        return tag.eval_page;
    }

}

在web-inf目录下的itcast.tld文件中添加对该标签处理类的描述,如下:


    demo4
    cn.itcast.web.tag.tagdemo4
    
    jsp

在jsp页面中导入并使用自定义标签,如下:

<%@ page language="java" contenttype="text/html; charset=utf-8"
    pageencoding="utf-8"%>
<%@ taglib uri="http://www.itcast.cn" prefix="itcast" %>

<%-- 如果编写的java类实现了bodytag接口,那这时可以控制开始标签对应的方法dostarttag()返回eval_body_buffered 只要返回eval_body_buffered,服务器拿到标签体之后,它会把标签体作为一个对象通过setbodycontent()方法传递给 标签处理器类,接下来可以在结束标签对应的方法doendtag()方法里面拿到标签体,从而可以对标签体修改后输出。 --%> aaaaaaaaaaaaa

运行效果如下:
JSP传统标签开发

jsp传统标签开发总结

在现在的jsp标签开发中,很少直接使用传统标签来开发了,目前用得较多的都是简单标签,所以jsp的传统标签开发了解一下即可,下一篇重点介绍jsp简单标签的开发。