自定义标签

自定义标签主要用于移除 Jsp 页面中的 java 代码
 
 移除 jsp 页面中的 java 代码,只需要完成两个步骤:
编写一个实现 Tag 接口的 Java 类,并覆盖 doStartTag 方法,把 jsp 页面中的 java 代码写到 doStartTag 方法中。
编写标签库描述符( tld )文件,在 tld 文件中对自定义标签进行描述。
完成以上操作,即可在 JSP 页面中导入和使用自定义标签。
 
Tag接口的执行流程
l JSP 引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照 JSP 规范定义的通信规则依次调用它的方法。

  1public voidsetPageContext(PageContext pc)JSP引擎实例化标签处理器后,将调用setPageContext方法将JSP页面的pageContext对象传递给标签处理器,标签处理器以后可以通过这个pageContext对象与JSP页面进行通信。

  2public void setParent(Tag t)setPageContext方法执行完后,WEB容器接着调用的setParent方法将当前标签的父标签传递给当前标签处理器,如果当前标签没有父标签,则传递给setParent方法的参数值为null

  3public int doStartTag(),调用了setPageContext方法和setParent方法之后,WEB容器执行到自定义标签的开始标记时,就会调用标签处理器的doStartTag方法。

  4public int doEndTag()WEB容器执行完自定义标签的标签体后,就会接着去执行自定义标签的结束标记,此时,WEB容器会去调用标签处理器的doEndTag方法。

  5public void release(),通常WEB容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务器,直至停止web应用时,web容器才会调用release方法。

 

自定义标签功能扩展

l 自定义标签除了可以移除 Jsp 页面中的 java 代码外,它还可以用于完成一些页面逻辑,例如:
通过自定义标签可以控制 jsp 页面某一部分内容是否执行。
例如: <c:if> 标签
通过自定义标签可以控制标签后的 jsp 页面是否执行。
通过自定义标签可以控制 jsp 页面某一部分内容重复执行。
例如: <c:foreach> 标签
通过自定义标签可以修改 jsp 页面内容输出。
ltld文件中的四种标签体类型
EMPTY JSP  scriptless  tagdepentend

 

自定义标签
注:左边部分为传统标签,右边为简单标签
 
简单标签
l 由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN 公司为降低标签技术的学习难度,在 JSP 2.0 中定义了一个更为简单、便于编写和调用的 SimpleTag 接口来实现标签的功能。实现 SimpleTag 接口的标签通常称为简单标签。简单标签共定义了 5 个方法:
setJspContext 方法          setParent getParent 方法           setJspBody 方法                 doTag 方法
 
l setJspContext 方法
用于把 JSP 页面的 pageContext 对象传递给标签处理器对象
l setParent 方法
用于把父标签处理器对象传递给当前标签处理器对象
l getParent 方法
用于获得当前标签的父标签处理器对象
l setJspBody 方法
用于把代表标签体的 JspFragment 对象传递给标签处理器对象
l doTag 方法
用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在 doTag 方法中可以抛出 javax.servlet.jsp.SkipPageException 异常,用于通知 WEB 容器不再执行 JSP 页面中位于结束标记后面的内容,这等效于在传统标签的 doEndTag 方法中返回 Tag.SKIP_PAGE 常量的情况。
 
SimpleTag接口方法的执行顺序
l web 容器开始执行标签时,会调用如下方法完成标签的初始化
WEB 容器调用标签处理器对象的 setJspContext 方法,将代表 JSP 页面的 pageContext 对象传递给标签处理器对象。
WEB 容器调用标签处理器对象的 setParent 方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下, WEB 容器才会调用这个方法。
如果调用标签时设置了属性,容器将调用每个属性对应的 setter 方法把属性值传递给标签处理器对象。如果标签的属性值是 EL 表达式或脚本表达式,则 WEB 容器首先计算表达式的值,然后把值传递给标签处理器对象。
如果简单标签有标签体,容器将调用 setJspBody 方法把代表标签体的 JspFragment 对象传递进来。
l 执行标签时:
容器调用标签处理器的 doTag() 方法,开发人员在方法体内通过操作 JspFragment 对象,就可以实现是否执行、迭代、修改标签体的目的。
 
JspFragment
l javax.servlet.jsp.tagext.JspFragment 类是在 JSP2.0 中定义的,它的实例对象代表 JSP 页面中的一段符合 JSP 语法规范的 JSP 片段,这段 JSP 片段中不能包含 JSP 脚本元素。
l
l WEB 容器在处理简单标签的标签体时,会把标签体内容用一个 JspFragment 对象表示,并调用标签处理器对象的 setJspBody 方法把 JspFragment 对象传递给标签处理器对象。 JspFragment 类中只定义了两个方法,如下所示:
l getJspContext 方法
用于返回代表调用页面的 JspContext 对象 .
l publicabstract void invoke(java.io.Writer out)
用于执行 JspFragment 对象所代表的 JSP 代码片段
参数 out 用于指定将 JspFragment 对象的执行结果写入到哪个输出流对象中,如果传递给参数 out 的值为 null ,则将执行结果写入到 JspContext.getOut() 方法返回的输出流对象中。 ( 简而言之,可以理解为写给浏览器
 
invoke方法详解 
l JspFragment.invoke 方法可以说是 JspFragment 最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。例如:
在标签处理器中如果没有调用 JspFragment.invoke 方法,其结果就相当于忽略标签体内容;
在标签处理器中重复调用 JspFragment.invoke 方法,则标签体内容将会被重复执行;
若想在标签处理器中修改标签体内容,只需在调用 invoke 方法时指定一个可取出结果数据的输出流对象(例如 StringWriter ),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。
 
开发带属性的标签
l 自定义标签可以定义一个或多个属性,这样,在 JSP
页面中应用自定义标签时就可以设置这些属性的值,通过这些属性为标签处理器传递参数信息,从而提高标签的灵活性和复用性。
l 要想让一个自定义标签具有属性,通常需要完成两个任务:
在标签处理器中编写每个属性对应的 setter 方法
TLD 文件中描术标签的属性
l 为自定义标签定义属性时,每个属性都必须按照 JavaBean 的属性命名方式,在标签处理器中定义属性名对应的 setter 方法,用来接收 JSP 页面调用自定义标签时传递进来的属性值。例如属性 url ,在标签处理器类中就要定义相应的 setUrl(String url) 方法。
l 在标签处理器中定义相应的 set 方法后, JSP 引擎在解析执行开始标签前,也就是调用 doStartTag 方法前,会调用 set
属性方法,为标签设置属性。
l
TLD中描述标签属性
自定义标签
 

<tag>元素的<attribute>子元素用于描述自定义

标签的一个属性,自定义标签所具有的每个属性

都要对应一个<attribute>元素

<attribute>

  <description>description</description>

  <name>aaa</name>

  <required>true</required>

  <rtexprvalue>true</rtexprvalue>

  <type>ObjectType</type>

</attribute>

 

如果不知tld文件如何写,可到D:\app\apache-tomcat-7.0\webapps\examples\WEB-INF\jsp目录下的示例tld文件做参考

自定义标签打包

新建一个Java Project,将所写的java标签处理类(包括包名)拷贝到该工程,在根目录下新建一个META-INF目录,将tld文件放到该目录下,然后以jar包(去掉描述IDE环境的配置文件,如eclipse下有.classpath,.project等)的形式导出该Project即可。

 

 

你可能感兴趣的:(自定义标签)