jsp学习笔记4

 

JSP自定义标签(tag)

 

什么是自定义标签

 

1,用户自定义的Java语言元素, 实质是运行一个或者两个接口的JavaBean;

2,可以非常机密地和JSP的表示逻辑联系在一起,又具有和普通JavaBean相同的业务逻辑处理能力;

3,当一个JSP页面转变为servlet时,其间的用户自定义标签转化为操作一个称为标签hander的对象;

4,可操作默认对象,处理表单数据,访问数据库以及其它企业服务;

 

自定义标签库的特点

 

1,通过调用页面传递参数实现定制;

2,访问所有对JSP页面可能的对象;

3,修改调用页面生成的响应;

4,自定义标签间可相互通信;

5,在同一个JSP页面中通过标签嵌套,可实现复杂交互。

 

如何使用自定义标签库

 

1,声明标签库

2,使标签库执行对Web应用程序可用

 

声明标签库

 

1,使用taglib指令声明标签库

2,语法:<%@taglib uri="URI" prefix="pre" %>

 

注意:a. uri属性可以是绝对的,也可以是相对URL,该URL指向标记库描述符(TLD)文件;     

      b. uri属性也可以是一个并不存在的URL,该URL为web.xml文件中将标记库描述符(TLD)文件的绝对

 

URL到本地系统的一个映射;

 

3,范例:<%@taglib uri="/WEB-INF/template.tld" prefix="test" %>              

         <%@taglib uri="http://java.sun.com/jstl/core" prefix="core" %>      

 

使标签库执行可用

 

方式一:在WEB-INF/classes目录下部署标记处理程序类;

方式二:将标记处理程序类打包成jar文件并置于WEB-INF/lib目录。

 

几种典型的标签

 

1,不带属性和主体的简单标签:<mytaglibs:SomeTag/>;

2,不带主体但有属性的标签:<mytaglibs:SomeTag user="TonyDeng"/>;

3,带有主体和属性的标签:

         <mytaglibs:SomeTag user="TonyDeng">                                                              

                  ...// 标签体                                 

         </mytaglibs:SomeTag>;

 

注意:a. 属性列于start tag中,它是在标记库描述符(TLD)文件中指定,服务于标记库的自定义行为;       

      b. 标签体位于start tag和end tag间,可以是任何合法的JSP内容或者标签;

 

定义标签

 

1,开发实现tag的类(tag handler);

2,编辑标记库描述符(TLD)文件;

3,在web.xml中为标记库描述符(TLD)文件的绝对URL建立一个映射(该步骤可选);

 

标记库描述符(TLD)文件

 

1,一个描述标记库的XML文件;

2,内容开始是整个库的描述,然后是tag的描述;

3,标记库描述符(TLD)文件用于Web Container确认tag以及JSP页面发展工具;

 

实现tag的类(标签处理器)(tag handler)

 

1,是一些在引用了标签的JSP页面执行期间被Web Container调用以求自定义标签值的对象;

2,必须实现Tag, SimpleTag和BodyTag之一;

3,可以继承TagSupport和BodyTagSupport之一。

 

标签库的接口和类的继承关系接口的继承关系:      

☉ interface javax.servlet.jsp.tagext.JspTag         

        ☉ interface javax.servlet.jsp.tagext.SimpleTag            

        ☉ interface javax.servlet.jsp.tagext.Tag            

         ☉ interface javax.servlet.jsp.tagext.IterationTag            

         ☉ interface javax.servlet.jsp.tagext.BodyTag

 

类的继承关系:      

         ☉ class javax.servlet.jsp.tagext.TagSupport

          (implements javax.servlet.jsp.tagext.IterationTag, java.io.Serializable)          

                ☉ class javax.servlet.jsp.tagext.BodyTagSupport

                 (implements javax.servlet.jsp.tagext.BodyTag)       

         ☉ class javax.servlet.jsp.tagext.SimpleTagSupport

            (implements javax.servlet.jsp.tagext.SimpleTag)

 

 

                  (Interface)                   

                     JspTag                     

                        |                             

                |ˉˉˉˉˉˉˉˉ|            

           (Interface)      (Interface)JSP2.0            

               Tag           SimpleTag ←--SimpleTagSupport             

                |                                         

                |            

            (Interface)          

           IterationTag←--TagSupport

           支持迭代的标签         |

                |                 |          

                |                 |   

            (Interface)           |               

             BodyTag ←---BodyTagSupport

            可以处理标签体

 

 

自定义标签的开发步骤

 

1,写标签处理器,也就是一个符合自定义标签规范的类 xxx.java

2,写标签库定义文件,也就是定义标签的格式规范,也要符合自定义标签的规范 xxx.tld

3,建上述两步中的相应   文件进行部署。web.xml

 

tld文件中的配置

  <tag>

    <name>loop</name>

    <tag-class>com.tag.LoopTag</tag-class>

    <body-content>jsp</body-content>

    <!--设定自定义标签体内的内容,可以置为empty,也就是只能写空标签-->

    <attribute>

      <name>counter</name><!--配置自定义标签的属性名-->

      <required>true</required><!--配置属性是否必须出现-->

      <rtexprvalue>true</rtexprvalue><!--允许使用表达式作为属性的值-->

      <type>int<type><!--配置属性的类型-->

      </attribute>

  </tag>

 

 

简单的标签处理程序类

 

1,必须实现Tag接口的doStartTag()和doEndTag()方法;

2,因为不存在Body,doStartTag()方法必须返回SKIP_BODY;

3,如其余页面要执行,doEndTag()方法返回EVAL_PAGE, 否则返回SKIP_PAGE;

4,对于每一个标签属性,你必须在标签处理程序类里定义一个特性以及get和set方法以一致于JavaBeans   体系惯例

 

带Body的自定义标签

 

1,必须实现Tag接口的doStartTag()和doEndTag()方法;

2,可以实现IterationTag接口的doAfterBody()方法;

3,可以实现BodyTag接口的doInitBody和setBodyContent方法;

4,doStartTag方法可以返回SKIP_BODY、EVAL_BODY_INCLUDE、或者EVAL_BODY_BUFFERED(当你想使用     BodyContent);

5,doEndTag方法可以返回SKIP_PAGE或EVAL_PAGE;

6,doAfterBody方法可以返回EVAL_BODY_AGAIN, SKIP_BODY;

 

定义脚本变量的标签(迭代标签)

 

1,定义脚本标签的二个步骤:  

   . 在标记库描述符(TLD)文件中列明脚本变量;  

   . 定义标签扩展信息类(TEI)并且在TLD文件中包括这个类元素(tei-class);

2,变量必须在标签处理程序类中使用pageContext.setAttribute()方法设置;

3,标签扩展信息类(TEI)必须继承TagExtraInfo以及覆盖getVariableInfo()方法;

4,变量的范围可以是AT_BEGIN, NESTED, AT_END(标签扩展信息类(TEI)的VariableInfo中定义)之一;

 

脚本变量的有效性

变量     |   有效性                   

---------------------------------------

NESTED   | 标签中的参数在starttag到endtag之间是有效的

AT_BEGIN | 标签中的参数在标签的开始到JSP页面结束是有效的

AT_END   | 标签中的参数在标签的结束到JSP页面结束是有效的

 

Tag接口的方法

 

interface javax.servlet.jsp.tagext.Tag

------------------------------------------------------

+EVAL_BODY_INCLUDE:int

+EVAL_PAGE:int//继续执行页面

+SKIP_BODY:int//跳出标签体

+SKIP_PAGE:int//跳出页面,也就是整个JSP不会再运行

------------------------------------------------------

+release():void

+getParent():javax.servlet.jsp.tagext.Tag

+setParent(javax.servlet.jsp.tagext.Tag):void

+doEndTag():int

+doStartTag():int

+setPageContext(javax.servlet.jsp.PageContext):void

 

Tag的生命周期

 

1,setPageContext(javax.servlet.jsp.PageContext):void

2,setParent(javax.servlet.jsp.tagext.Tag):void

3,setAttribute:void

4,doStartTag():int

5,doEndTag():int

6,release():void

 

BodyTag和Tag接口的关系

 

interface javax.servlet.jsp.tagext.BodyTag-->interface javax.servlet.jsp.tagext.Tag

------------------------------------------

+EVAL_BODY_AGAIN:int//继续执行标签体

-----------------------------------------

+doInitBody():void

+setBodyContent(javax.servlet.jsp.tagext.BodyContext):void

+doAfterBody():int

 

BodyTag的处理过程

 

1,setPageContext(javax.servlet.jsp.PageContext):void

2,setParent(javax.servlet.jsp.tagext.Tag):void //设置此标签的父标签,也就是上一层标签

3,setParent()

4,doStartTag():int

5,setBodyContent(javax.servlet.jsp.tagext.BodyContent):void//设置方法体

6,doInitBody():void//

7,doAfterBody():int

/* 这个方法会被不断的调用直到不再满足条件,通过这个方法来控制返回,从而控制循环是否中断

  SKIP_BODY是跳出标签体的,EVAL_BODY_INCLUDE是继续执行标签体,通过返回这两个值来控制循环是否*/

8,doEndTag():int

9,release():void

 

SimpleTag接口的方法

 

javax.servlet.jsp.tagext.SimpleTag

------------------------------------------

+doTag():void

+getParent():JspTag

+setJspBody(JspFragment jspBody):void

+setJspContext(JspContext pc):void

+setParent(JspTag parent):void

 

SimpleTage接口的生命周期(JSP2.0的自定义标签接口)

1,new:      

   每次遇到标签,容器构造一个SimpleTag的实例,这个构造方法没有参数。和红典的标签一样,          SimpleTag不能缓冲,故不能重用,每次都需要构造新的实例。

2,setJspContext()、setParent(): 只有这个标签在另一个标签之,才调用setParent()方法;

3,设置属性:调用每个属性的setter方法;

4,setJspBody();

5,doTag(): 所有标签的逻辑、迭代和Body计算,都在这个方法中;

6,return

 

例:

 

package com.tag;

public class HelloTag implements Tag

{

  private PageContext pageContext;

  private Tag parent;

 

     public HelloTag(){ 

    super();

     }

    

    /**

      *设置标签的页面的上下文

      */

     public void setPageContext(final PageContext pageContext) {

           this.pageContext=pageContext; 

     }

    /**

      *设置上一级标签

      */

     public void setParent(final Tag parent) {  

          this.parent=parent;  

     }

     /**

      *开始标签时的操作

      */

     public int doStartTag() throws JspTagException{  

          return SKIP_BODY;  //返回SKIP_BODY,表示不计算标签体

     }

     /**

      *结束标签时的操作

      */

     public int doEndTag() throws JspTagException{

        try{  

             pageContext.getOut().write("Hello World!你好,世界!");

        }             

          catch(java.io.IOException e){

             throw new JspTagException("IO Error: " + e.getMessage());

          } 

          return EVAL_PAGE;

      }

     /**

      *release用于释放标签程序占用的资源,比如使用了数据库,那么应该关闭这个连接。

      */

     public void release() {}   

     public Tag getParent(){   

        return parent;

     }

}

 

xxx.tld

 

<?xml version="1.0" encoding="ISO-8859-1" ?>

<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">

 

  <tag>

    <description>Extends TagSupport</description>

    <name>hello</name>

    <tag-class>com.tag.HelloWorldTag</tag-class>

    <body-content>jsp</body-content>

  </tag>

</taglib>

 

web.xml

 

<web-app>

<taglib-uri>/xxx</taglib-uri>

 <taglib-location>/WEB-INF/tlds/xxx.tld</taglib-location>

</web-app>

 

xxx.jsp

 

<%@ taglib uri="/xxx" prefix="mytag" %>

<%@ page contentType="text/html; charset=gb2312" %>

<html><head><title>first cumstomed tag</title></head><body>

<p>以下的内容从Taglib中显示: </p>

<p><i><mytag:hello_int/></i>

<br>

<p><mytag:hello_int></mytag:hello_int>

</body></html>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值