如有错误欢迎指正
想学习自定义标签怎么写,最好先知道标签的执行原理和流程,可以帮助你写自定义标签的时候思路更加清晰,所我推荐你可以看一下我上篇博客,标准标签库(JSTL)执行原理详解(jsp,xml,tld,jar关系详解)_m0_59834108的博客-CSDN博客
正文开始:
标签只是一个代名词,我们用标签的时候其实是在用它所带来的功能,所以想用自定义标签,得创建一个定义这个标签的Java类,也就是用Java语言来写这个标签的功能。
用户在jsp页面中使用标签时,系统首先会先找到xml文件,通过xml,找到对应的tld文件,然后通过tld文件再找到对应的Java类
注意,在编写标签之前,必须把tomcat\lib中的jsp-api.jar文件配置在CLASSPATH中才可以;
假设我们想自定义一个标签叫作<ex:Hello> (ex是标签库的名字,Hello是标签的名字,所以这个标签其实是调用ex库中的Hello标签,所以要建立ex库并在其中建立Hello标签)
我们需要创建一个Java类,这个类有什么要求呢,慢慢来看
(可以结合下文中的实例一起理解,也许比较容易)
这个类必须继承javax.servlet.jsp.tagext.TagSupport;
TagSupport中提供了很多常用方法:
(1) public int doStartTag()throws JspException; // 标签开始时调用
能够返回SKIP_BODY(跳过标签体)、EVAL_BODY_INCLUDE(执行标签体)
(2) public int doEndTag()throws JspException; // 标签结束时调用
能够返回SKIP_PAGE(立刻停止执行)、EVAL_PAGE(JSP正常运行完毕);
(3) int SKIP_BODY; // 跳过标签体
(4) int EVAL_BODY_INCLUDE; //执行标签体
(5) int EVAL_BODY_AGAIN; // 重复执行标签体,主要是因为集合迭代输出,只能在doAfterBody中使用;
(6) public int doAfterBody()throws JspException; // 执行完一次标签体后调用的函数;
能够返回SKIP_BODY(结束标签体)、EVAL_BODY_AGAIN(重复执行标签体)
(7) JspWriter out = super.pageContext.getOut();//获取向网页输出的输出流;
接下来我们举一个实例
比如想在jsp页面这样用
<%@ page contentType="text/html" pageEncoding="GBK"%>
<%@ taglib prefix="ex" uri="xiazdong"%> //uri是自己取的一个名字,可以取任意值,需要与xml中的uri保持一致,才能从这里找到xml去
<html> prefix=ex表示给引用的标签库起个别名‘ex’,下文用这个标签库的时候可以直接用 <ex: >
<head>
<title></title>
</head>
<body>
<h1><ex:Hello/></h1>
</body>
</html>
现在去xml文件编写映射
<jsp-config>
<taglib>
<taglib-uri>xiazdong</taglib-uri> //这个uri与jsp文件中的uri对应
<taglib-location>/WEB-INF/classes/xiazdong.tld</taglib-location> //通过这个location可以去找tld文件
</taglib>
</jsp-config>
现在来写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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<tag>
<name>hello</name> <!--表示标签的名字 -->
<tag-class>org.tagext.HelloTag</tag-class> <!--定义标签的类 -->
<body-content>empty</body-content> <!--是否存在标签体-->
</tag>
//一个tag中的内容相当于配置一个标签
//整个tld文件相当于一个标签库,可以写很多tag建立很多标签
//例如 再写一个 <tag> //.... </tag>
</taglib>
写HelloTag.java
package XXX
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
public class HelloTag extends TagSupport{
public int doStartTag()throws JspException{
JspWriter out = super.pageContext.getOut();
try{
out.println("<h3>Hello world!!!</h3>");
}
catch(Exception e){}
return TagSupport.SKIP_BODY;
}
}
经过对xml ,tld 和java的编写,一个标签就完成了
但是这个标签没有属性,接下来我们再来看看怎么给这个标签添加属性
比如要写一个jsp是这样的
<%@ page contentType="text/html" pageEncoding="GBK"%>
<%@ taglib prefix="ex" uri="xiazdong"%>
<html>
<head>
<title></title>
</head>
<body>
<h1><ex:hello name="xiazdong" age="20"/></h1>
</body>
</html>
xml文件只是一个映射作用,不用改变。
现在来修改tld文件,用<attribute>在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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>x</short-name>
<tag>
<name>Hello</name>
<tag-class>org.tagext.HelloTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name> //属性名
<required>true</required> //属性是否必要
<rtexprvalue>empty</rtexprvalue> //是否支持表达式语言
</attribute>
<attribute>
<name>age</name>
<required>true</required>
<rtexprvalue>empty</rtexprvalue>
</attribute>
</tag>
</taglib>
java类中的代码,需要加入name和age
package org.tagext;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
public class HelloTag extends TagSupport{
private String name;
private String age;
public String getName(){
return name;
}
public String getAge(){
return age;
}
public void setName(String name){
this.name = name;
}
public void setAge(String age){
this.age = age;
}
public int doStartTag()throws JspException{
JspWriter out = super.pageContext.getOut();
try{
out.println("<h3>姓名:"+name+"</h3>");
out.println("<h3>年龄:"+age+"</h3>");
}
catch(Exception e){}
return TagSupport.SKIP_BODY;
}
}
这样就可以用有属性的标签了
如有错误欢迎指正
本文大部分参考自JSP自定义标签详解_real.me-CSDN博客