- 什么是标签库
标签库是jsp页面要使用的标签元素的集合,前面笔记总结的都是默认的标签,容器提供了另外几套标准标签库和用户自定以标签库来零化jsp页面中java代码,我将不笔记标准标签 库的各个细则,只约略记录一下sun公司提供的几个标签有:c/fmc/sql/x/fn几个前缀标识,它封装了程序员常用的一些标签,我个人是不提倡用这些标签因为难以记忆,如果有公司 采用这样的技术手段,只需要查规范即可,标签本质上只是java代码的标签化而已。然后如果有公司使用自定义标签库,则只需要知道标签库如何自定义和使用即可。下面的内容 将围绕自定义标签展开。
一个标签的组成
标签概念的完全组成部分是空标签、标签属性和标签体。自定义的标签实际上就是实现了传统标签和简单标签接口的java类,然后完成标签类的部署工作后,程序员就可以在jsp中 使用。
- 标签接口在容器中的生命周期:
javax.servlet.jsp.tagext.Tag接口作为顶级接口定义了标签需要实现的基本方法,其相关类的静态层次这里忽视,只约略笔记相关的几个周期方法:
1.1容器在创建标签处理器的实例后(需要部署告知容器),调用setPageContext()方法设置标签的页面上下文,然后调用setParent()设置此标签的父标签,没有则为null;
1.2调用标签处理器的setXXX(),设置标签的属性,如果jsp中的标签定义属性则没有这一步骤;
1.3调用doStartTag()方法,如果返回EVAL_BODY_INCLUDE常量(接口中定义的),则将标签体输出到当前的输出流中;如果返回SKIP_BODY则忽略标签体。
1.4调用doEndTag()方法,返回PAGE,则执行jsp页面之余,返回SKIP_BODY则忽略页面之余;和上一步骤类似,该步骤中的代码会原样编写进jsp对应的servlet代码中。
1.5容器缓存该实例,重复使用;
1.6需要释放该实例时,调用release();
知道了其生命周期后,我们就可以实现简单标签或传统标签接口,在对应的方法中写入合适的处理内容。
2.标签实现类的部署
完成标签处理器的编写后,需要告知容器该处理器的信息,让容器拥有对处理器的管理权。
2.1标签库描述符(Tag Library Descriptor,TLD)
编写.tld文件到META-INF或WEB-INF目录下(最好创建自目录tags),下面贴上一个案例:
代码结构:
编写便签处理器HelloTag.java
package tags; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.Tag; //实现传统标签接口 public class HelloTag implements Tag{ private PageContext pageContext; private Tag parent; //设置context对象 public void setPageContext(PageContext pc) { this.pageContext=pc; } //如果标签嵌套,设置父标签 public void setParent(Tag t) { this.parent=t; } //获取父标签 public Tag getParent() { return parent; } //当处理标签时,该方法被调用 public int doStartTag() throws JspException { return SKIP_BODY;//有效返回值0,跳过body评估,即忽略标签体 } //当处理结束时,该方法被调用 public int doEndTag() throws JspException { JspWriter out = pageContext.getOut(); try { out.println("欢迎来到我的个人网站!"); }catch(IOException e) { System.out.println(e.toString()); } return EVAL_PAGE;//返回6,继续评估该page,即jsp页面的余下部分继续执行 } @Override public void release() {}//释放标签处理器资源 }
标签描述文件MyTaglib.tld
<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.1"> <tlib-version>1.0</tlib-version> <short-name>my</short-name><!-- 为标签库定义一个简短名字,jsp页面编辑使用 ,作为首先前缀值使用--> <display-name>My Tag</display-name><!-- 为标签库指定一个简短名字,被一些工具所显示 --> <discription>Custom Tag library</discription> <tag><!-- 没有属性没有标签体的标签 --> <name>hello</name> <tag-class>tags.HelloTag</tag-class> <body-content>empty</body-content> </tag> <tag><!-- 带属性 的标签 --> <name>max</name> <tag-class>tags.MaxTag</tag-class> <body-content>empty</body-content> <attribute> <name>num1</name> <required>true</required><!-- 设置标签属性为必填 --> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>num2</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag><!-- 带标签体的标签 --> <name>greet</name> <tag-class>tags.GreetTag</tag-class> <body-content>JSP</body-content><!-- 代表标签体可以包含jsp代码 --> </tag> <!-- <description/> 为标签库提供一个文本描述 <smaill-icon/> 为标签库提供小图标 <large-icon/> 为标签库提供大图标 <validator> 标签库的验证器 <description></description> 为验证器提供一个文本描述 <validator-class></validator-class> 指定验证的实现类 <init-param></init-param> 验证类的初始化参数 </validator> <listener> 标签库的监听器 <description/> 监听器提供一个文本描述 <dispalay-name/> 简短名字 <icon> 指定图标 <small-icon/> 指定小图标 <large-scon/> 大图标 </icon> <listener-class/> 指定监听器类完全限定名 </listener> <tag>指定标签的配置信息 <description/> 为标签库提供一个文本描述 <display-name></display-name> 为标签指定一个简短名字 <icon> <small-icon/><large-icon/> </icon> <name></name> 指定自定义标签的名字 <tag-class/> 指定标签的实现类 <tei-class/> 为容器在转换阶段提供该标签的附加信息 <body-content/> 指定标签体的格式 </tag> <tag-file> 关于该标签文件的信息 <description/> 标签文件提供一个文本描述 <display-name/> 为标签文件提供一个简短名 <icon/> 为标签文件指定大小图标,省略子标签 <name/> 指定标签文件的名字 <path/> 指定标签文件的路径 <example/> 提供一个使用例子描述 <tag-extension/> 提供标签的扩展信息 </tag-file> <function> 与EL表达式有关 <description/> 为EL函数指定一个简短名字 <icon/> 指定一个图标 ,子标签省略 <name/> 给函数指定一个名字 <function-class/> 实现el函数的类完全限定 <function-signture/> 指定EL函数的原型 <example/> 提供一个使用案例 <function-extension/> 提供额外信息 </function> --> </taglib>
可以看到,文件中每一个tag标签就是对一个实现Tag接口的处理器的描述,标签的name属性,作为jsp中指示要使用的标签的标识,jap中使用标签库+标签名的方式来定位要使 用的标签。标签库会在web.xml中进行说明。
标签库在容器中的部署web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <!-- 标签即动作!! --> <!-- 对自定义标签的部署,即容器启动时就根据部署文件找到tld,再根据tld找到对应的标签实现类,再jsp的解析过程中遇到标签就替换成对应的实现类代码 --> <jsp-config><!-- 为jsp提供全局配置信息 --> <taglib><!-- 为页面的tag提供部署 --> <taglib-uri>/mytag</taglib-uri><!-- 对应jsp中的uri标识 --> <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location> </taglib> </jsp-config> </web-app>
该文件中主要告知容器标签库的描述文件,让容器启动时根据描述文件加载标签处理器。
自定义标签的使用hello.jsp
<%@ page language="java" contentType="text/html; charset=gb2312"%> <%@ taglib uri="/mytag" prefix="my" %><!-- 指定标签库及其简短表示,根据uri去部署描述文件中寻找对应的标签描述文件即可找到对应的标签类 --> <html> <head> <title><my:hello/></title><!-- 说明使用标签库中的某个标签 --> </head> <body> <my:hello/> </body> </html>
总结:尽管个人不是很提供使用标签,但是不排除有技术成熟的公司在使用,如果项目中遇到,则以上的案例作为基本的操作指南:在jsp中使用taglib指令说明要使用的标签所在的标签库,即web.xml中对应标签库描述文件的uri标识;找到标签文件所在位置打开,查找标签库的short name作为jsp中taglib指令的prefix,即可在使用某个标签时使用前缀+标签名的方式定位要使用的标签;在标签文件中找到要使用的tag标签name,就可以标签库前缀+标签名使用了。标准标签库可以理解为sun公司给写好的自定义标签,文章开始已经谈到就不再赘述,如果要使用就可以直接再jsp中使用taglib指令和前缀+标签的方式使用即可。EL表达式可以理解为对javabean的直接访问,也不作为重点学习目标,因为他们本质上只是简化jsp中的java代码而已,如果用到可以查阅规范!