自定义标签
正常:包含起始标签,标签体,结束标签
空标签: 没有标签体,但可包含标签属性
嵌套标签: 自定义标签内包含其他自定义标签
如何开发自定义标签:
* 定义需求
* 定义标签形式
* 编写标签处理器
* 编写标签的描述文件tld
* 在web.xml文件中制定tld的位置,servlet2.4,jsp2.0以上版本,不用配置此项
* JSP页面导入和使用标签
如何开发自定义标签:
* 定义需求:遍历集合
<yxk:forEach items="${lists}" var="per"> ${per.name }----${per.age }<br/> </yxk:forEach>
* 定义标签处理类,实现SimpleTag接口
public class DateTag implements SimpleTag { private PageContext pageContext;//上下文对象 private JspFragment jspBody;//标签体 private Object items; private String var; /** * 1 jsp引擎将调用该方法, * * 将代表jsp页面的pageContext对象,传递给该方法 */ public void setJspContext(JspContext pc) { this.pageContext=(PageContext) pc; } /** * 2 jsp引擎将调用该方法, * * 设置属性Items */ public void setItems(Object items) { this.items = items; } /** * 2 jsp引擎将调用该方法, * * 设置属性var */ public void setVar(Object var) { this.var = var.toString(); } /** * 3 jsp引擎将调用该方法, * * 设置代表jsp页面的标签体内容传递给该方法 */ public void setJspBody(JspFragment jspBody) { this.jspBody = jspBody; } /** * 4 jsp引擎调用 * 容器调用标签处理器对象的doTag 方法执行标签逻辑 */ public void doTag() throws JspException, IOException { if (items != null) { Iterator it = null; //实现list和set,父类时Collection if (items instanceof java.util.Collection) { it = ((Collection) items).iterator(); } //实现数组 if(items instanceof java.lang.Object[]){ List lists=Arrays.asList((Object[])items); it=lists.iterator(); } //实现map if(items instanceof java.util.Map){ Map maps=(Map)items; Set sets=maps.keySet(); for(Iterator itt=sets.iterator();itt.hasNext();){ String keys=itt.next().toString(); KeyValueSet kvs=new KeyValueSet(keys, maps.get(keys)); System.out.println("sdf"); pageContext.setAttribute(var, kvs); this.jspBody.invoke(null); } } if (it != null) { while (it.hasNext()) { Object obj = it.next(); pageContext.setAttribute(var, obj); this.jspBody.invoke(null); } } } } }
* 建立标签和标签处理类的关联
* 创建mytag.tld文件,放置到/WEB-INF/tld中
* 内容如下:
<?xml version="1.0" encoding="UTF-8" ?> <taglib 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-jsptaglibrary_2_1.xsd" version="2.1"> <!-- 该标签库的描述 --> <description>myJSTL 1.0 core library</description> <!-- 该标签库的概述 --> <display-name>MyJSTL core</display-name> <!-- 标签库的版本 --> <tlib-version>1.0</tlib-version> <!--在jsp页面建议使用的前缀名--> <short-name>yxkong</short-name> <!--给标签库起一个唯一的名称,可以通过该名称在外部找到mytag.tld文件 --> <uri>http://yxkong.com/jsp/myjstl/mytag</uri> <!-- 配置lwq:forEach标签--> <tag> <!-- 在jsp页面使用的标签的名称 --> <name>forEach</name> <!-- 标签处理类的完整路径 --> <tag-class>cn.yxk.myTag.ForEachTag</tag-class> <!-- 配置标签体的类型如果是 empty:表示标签体为空--> <!-- 表示标签体可以包含El表达式和动作元素,但不能包含jsp的脚本元素System.out.println("xxxxx") * scriptless:对el表达式,解析传递给标签处理类的是运行后的结果 * tagdependent:原样输出,对el表达式不解析 --> <body-content>scriptless</body-content> <!--配置标签体的属性--> <attribute> <!-- 配置属性的名称,该名称根标签中的属性名称一致,同时还要和标签处理类中的setItems的属性名称一致--> <name>items</name> <!-- true表示该属性是必须存在的,false:表示该属性不是必须存在的 --> <required>true</required> <!--表示运行时表达式的值(runtime expression value) true:支持运行时表单式的值 false表示不支持运行时表达式的值 --> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>var</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
* 在jsp页面如何使用
* 使用<%@ taglib uri="/WEB-INF/tld/mytag.tld" prefix="yxk"%>引入
* taglib:jsp的标准指令,用于引入标签库
* uri:通过该地址可以找到标签库文件(mytag.tld).
* 可以使用/WEB-INF/tld/mytag.tld
* 使用mytag.tld的uri标签的值 http://yxkong.com/jsp/myjstl/mytag
* prefix="yxk":使用的前缀名,其他别名,一般情况下和<short-name>lwq</short-name>一致
* <yxk:forEach items="${lists}" var="per">
${per.name }----${per.age }<br/>
</yxk:forEach>
* tld文件的存放位置,不用在web.xml文件配置.
* Tld 文件可以放置在 web 应用程序的 WEB-INF 目录及其子目录中
* 不能放置在 WEB-INF 目录下的 classes 和 lib 子目录中
* tld 文件也可以放置在 WEB-INF\lib 目录下的 jar 包的 META-INF 目录及其子目录中
* 查找顺序:
* 现在WEB-INF目录下查找,如果找不到再到WEB-INF\lib的jar包中查找[自动查找]
实现SimpleTag借口的标签处理器类的生命周期
1 setJspContext()
jsp引擎将调用该方法,将代表jsp页面的pageContext对象,传递给、标签处理器对象
2 setParent
jsp引擎将父标签处理器对象传递给当前标签处理器对象。只有存在父标签时,jsp引擎才会调用该方法
3 set***
设置标签属性。只有定义了属性才会调用该方法
4 setJspBody
若存在标签体,JSP引擎将把标签体封装成一个jspFragment对象,调用setJspBody方法将JspFragment对象传递给标签处理器对象。若标签体为空,这个方法将不会被调用
5 doTag()
容器调用标签处理器对象的doTag方法执行标签逻辑
开发自定义标签的过程
<descripttion>标签库的描述</descripttion> <display-name>标签库概述</display-name> <tlib-version>标签库版本 --必须的</tlib-version> <short-name>在jsp页面中引用的前缀名 必须的</short-name> <uri>给标签库起一个唯一的名称,可以通过该名称在外部找到tld文件 不是必须的,放到web-inf下可以自动装载</uri> <tag> <name>在jsp页面使用的标签的名称</name> <tag-class>标签处理器 类的完路径 必须的</tag-class> <body-content>标签体的内容,设置为empty表示标签体是空的 必须的</body-content> 表示标签体可以包含EL表达式和动作元素,但不能包含jsp的脚本元素 |--scriptless :对EL表达式支持,解析传递给标签处理类的值是运行后的结果 | --tagdependent:原样输出,对EL表达式等不解析 <attribute> <name>配置标签属性的名称,该名称跟标签中的属性名称必须一致,而且还要和标签处理器中的名称要一致</name> <required>true表示该属性在标签中是必须属性,使用时不可少</required> <rtexprvalue>true:表示该标签的此属性支持El等表达式,false则不会编译表达式 </rtexprvalue>(runtime expresstion value 的缩写) </attribute> </tag>
文章评论