自定义标签的概述:
(1)用户自定义的一种jsp标记。自定义标签将那些重复工作进行封装,从而提高了工程生产力,而且将具有共用特性的标签库应用于不同的项目中,体现了软件复用的思想。
(2)当一个含有自定义标签的jsp页面被jsp引擎(Web容器)编译成servlet时,标签将被转化成对一个称为tag处理类的对象的操作。之后当JSP页面对应的servlet被执行时,jsp引擎就调用这些操作。
标签的形式
<前缀:标签名 属性名1=值1属性名2=值2 …>标签主体</前缀:标签名>
一个标签可以没有属性或者没有主体,也可以同时没有属性和主体。没有主体的标签可以简写成这样的形式:<前缀:标签名 属性名1=值1 …/>、<前缀:标签名/>
[b]3.自定义标签的优点[/b]
(1)分离了程序逻辑和表示逻辑。
(2)将Java代码从HTML中剥离,便于美工维护页面。
(3)减少了JSP页面中的脚本,减少了维护成本。
(4)提供了可重用的功能组件。
4.自定义标签库(Custom Tag library)
由一系列功能相似、逻辑上互相联系的自定义标签构成的集合称为标签库。
5.创建自定义标签的方式
a.java类文件方式
b.标签文件方式
标签文件是一种扩展名为tld的文件,它必须存储到web应用程序的web-inf目录中.标签文件的作用类似于标签处理文件,他是一个包含一些内容或jsp重要代码的jsp片段.当jsp遇见自定义标签时,他会跑到标签文件以执行标签定义.不需要一个单独的标签库描述符,因为标签文件包含了标签的完整时间.
java类文件创建和使用一个标签库的步骤基本如下:
(1)创建标签的处理类(tag handle class),定义标签的行为,并在jsp引擎遇见标签时调用执行.标签处理类是一个Java类,这个类继承了TagSupport或者扩展了SimpleTag接口,通过这个类可以实现自定义JSP标签的具体功能.
(2)创建标签库描述文件TLD(Tag Library Descrptor File).描述标签库的XML文档,像jsp引擎提供有关自定义标签的标签处理程序的信息
(3)在web.xml文件中申明tld的位置
(4)在jsp文件中用taglib引入标签库
(5)在jsp中使用标签库标签
6.创建标签的处理类
传统标签处理器在javax.servlet.jsp.tagext包中的接口和类
我们要写的自定义标签处理类主要继承自TagSupport、BodyTagSupport这两个类。通过继承这两个类,只需要重新定义那些需要自定义的行为的方法,从而简化了标签处理程序的开发。
简单标签处理器javax.servlet.jsp.tagext包中的接口和类。我们要写的自定义标签处理类继承自SimpleTagSupport类,重写doTag()方法。这是在JSP2.0新规范中增加的类,这个类实现自SimpleTag接口,之所以称其为“简单”是指它相对于传统标签处理器实现任务要简单得多。
agSupport类。TagSupport类并不能对标签主体的内容做任何处理,您所能决定的只是是否显示主体的内容。
生命周期
当jsp容器在解释jsp页面时,如果碰到了自定义标签,将利用标签处理类来建立一个"标签处理对象",在建立标签处理对象的过程中,jsp会根据自定义标签的属性值来初始化"标签处理对象"的属性值
首先,JSP容器会运行doStartTag()方法内的程序代码,然后根据此方法的返回值决定后续动作。如果返回
SKIP_BODY,表示要求JSP容器忽略标签主体的内容;如果返回E
VAL_BODY_INCLUDE,表示要求JSP容器要显示标签主体的内容,然后运行
doAfterBody()方法。
如果doAfterBody()方法传回
EVAL_BODY_AGAIN,表示要求JSP容器再次显示标签主体的内容,如果返回
SKIP_BODY,JSP容器将会运行
doEndTag()方法
最后,JSP容器会运行doEndTag()方法内的程序代码,并根据此方法的返回值决定后续动作:如果返回
SKIP_PAGE,JSP容器会运行release()方法,然后忽略自定义标签以后的JSP内容;如果返回
EVAL_PAGE,JSP容器会先运行release()方法,然后运行自定义标签以后的JSP内容。
生命周期主要方法
doStartTag()方法可返回的值有SKIP_BODY,忽略标签主体的内容(此方法的预设返回值);VAL_BODY_INCLUDE,表示要求JSP容器要显示标签主体内容。
● doAfterBody()方法可返回的值有以下几项。
SKIP_BODY:要求JSP容器忽略主体内容,进入标签处理程序的下一步工作(此方法的预设返回值)。
EVAL_BODY_AGAIN:要求JSP容器再次显示标签主体内容。
● doEndTag()方法可返回的值有以下几项
SKIP_PAGE:忽略自定义标签以后的JSP网页内容。
EVAL_PAGE:运行自定义标签以后的JSP网页内容(此方法的预设返回值)。
● release():释放标签处理对象所占用的系统资源。
BodyTagSupport类。
① 生命周期
BodyTagSupport与TagSupport的区别主要是标签处理类是否需要读取标签体的内容和改变标签体返回的内容,如果不需要交互的就用TagSupport,否则就用BodyTagSupport。
这里需要注意的是TagSupport也可以有体,如果将TagSupport理解成是没有体的标签,而将BodyTagSupport理解成是有体的标签就错了。当然用TagSupport实现的标签,都可以用BodyTagSupport来实现,道理很简单,因为BodyTagSupport继承了TagSupport。
② 生命周期主要方法
● doStartTag() 方法可返回的值有SKIP_BODY,表示要求JSP容器忽略主体内容;
EVAL_BODY_INCLUDE,表示要求JSP容器要显示标签主体内容;EVAL_BODY_BUFFERED 表示JSP容器会将标签主体的处理结果建立成一个BodyContent对象(此方法的预设返回值)。
● setBodyContent()方法会设置BodyContent对象的一些属性,包括标签主体的内容和在处理标签过程中要输出至response的数据对象。
● doInitBody()方法在第一次处理标签主体内容时,它将对主体进行初始化的工作。
● doAfterBody()方法可返回的值有SKIP_BODY,表示要求JSP容器忽略主体,进入下一步的处理工作;EVAL_BODY_AGAIN,表示要求JSP容器再次处理标签主体。
● doEndTag()方法可返回的值有SKIP_PAGE,表示忽略自定义标签以后的JSP网页内容; EVAL_PAGE,表示运行自定义标签以后的JSP网页内容。
● release()方法释放标签处理对象所占用的系统资源。
SimpleTagSupport类
当JSP容器遇到标记时,将标签处理类的默认构造方法建立一个标签处理实例。注意必须为每个标记都创建一个新的实例,这很重要。
在标记处理程序中调用setJspContext()和setParent()方法。如果传递的值是“null”,则不需要调用setParent()方法。在使用标记文件的情况下,创建一个JspContext包装,以便标记文件看上去具有其本身的页面范围。调用getJspContext()必须返回所包装的JspContext
容器为每个标记所定义的属性,同时也需要提高set方法,set方法是用来让外界设置属性的值,其顺序是它们出现在JSP页或标记文件中的顺序。如果属性值是表达式语言的表达式或运行时表达式,则它首先被赋值,然后被传递到设置器;另一方面,如果属性为动态属性,则调用setDynamicAttribute()
由容器调用setJspBody()方法,将该标记的主体设置为JspFragment;如果标记被声明为具有空的值,则将null值传递到setJspBody()
由容器调用doTag()方法。所有的标记逻辑、迭代、主体赋值等都在该方法中发生。
在doTag()方法返回后,所有的变量被同步。
撰写标签处理类
所撰写的标签处理类应该具备下列特性:
承TagSupport类或BodyTagSupport类或SimpleTagSupport类;
对自定义标签的属性声明相对应的变量,并提供一个setXXX()方法;
doStartTag()、doAfterBody()或doEndTag()方法(或doTag()方法)内撰写Java程序代码,实现自定义标签欲提供的功能。
好了,下面是自己写的一个简单的demo:
首先写一个标签处理类,是继承TagSupport,实现其中的doStartTag(),整个逻辑是,通过页面调用自定义标签,判断标签的value是不是admin 如果是admin.view就表示可以看到标签的内容,如果不是则不显示标签内容
package test.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
public class MyTag extends TagSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
private String permission;
@Override
public int doStartTag() throws JspException {
JspWriter writer = pageContext.getOut();
if(this.permission!=null&&!this.permission.equals("")){
if(this.permission.equals("admin.view")){
return EVAL_BODY_INCLUDE;
}else{
try {
writer.println("没有该权限");
} catch (IOException e) {
e.printStackTrace();
}
return SKIP_BODY;
}
}else{
try {
writer.println("没有该权限");
} catch (IOException e) {
e.printStackTrace();
}
return SKIP_BODY;
}
}
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
}
然后配置标签.tld文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- <!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> -->
<tlibversion>tlibversion</tlibversion> <!-- 你自定义标签的版本数 -->
<jsp-version>1.2</jsp-version> <!-- 指定你的JSP版本,扩张标签是在JSP1.2之后兼容的 -->
<shortname>shortname</shortname> <!-- 标签的简写 -->
<tag>
<name>tags</name> <!-- 标签名字 -->
<tagclass>test.tag.MyTag</tagclass> <!-- 指定你的标签的类 -->
</tag>
</taglib>
然后在web.xml配置jsp-config
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<jsp-config>
<taglib>
<taglib-uri>TestTagUri</taglib-uri>
<taglib-location>WEB-INF/testTag.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
最后在jsp页面使用该标签
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/WEB-INF/testTag.tld" prefix="out"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head></head>
<body>
<out:tags permission="admin.view">
<a>你有admin权限</a>
</out:tags>
</body>
</html>
测试是否OK:
启动服务器.在浏览器输入:http://localhost:8082/TestTag/HelloTag.jsp
得到如下结果:
你有admin权限
更改permission的值,那么结果就变成如下了:
哎,公司网速不给力,结果图片实在是传不上来,只能复制结果了
代码是之后自己回去复习时候写的一个小demo,和上面的demo差不多 只不过是显示在前端的标签