JSP自定义标签(标签处理器 tld文件)
标签的形式如下,标签处理器就是处理JSP页面中的标签的属性和内容,定义好之后就跟使用JSTL一样
<标签名 属性名="属性值" 属性名="属性值">
标签的内容
<子标签名 属性名="属性值" 属性名="属性值">
子标签的内容
</子标签名>
</标签名>
经典标签处理器(JSP2.0以前):实现接口Tag、IterationTag、BodyTag的标签处理器都叫做经典标签处理器。
简单标签处理器(JSP2.0引入):实现接口SimpleTag或者继承类SimpleTagSupport的标签处理器叫做简单标签处理器。
// 自定义标签的相关接口都在 javax.servlet.jsp.tagext包中
public interface Tag extends JspTag
public interface IterationTag extends Tag
public interface BodyTag extends IterationTag
public interface SimpleTag extends JspTag
public class SimpleTagSupport extends java.lang.Object implements SimpleTag // 提供了接口Simpletag的所有方法的默认实现
public abstract class JspFragment extends java.lang.Object
接口simpleTag和支持类SimpleTagSupport中的方法
// SimpleTag中的方法
void doTag() throws JspException, java.io.IOException
void setParent(JspTag parent)
JspTag getParent()
void setJspContext(JspContext pc)
void setJspBody(JspFragment jspBody)
// SimpleTagSupport中的方法 在SimpleTag基础上又增加了三个
protected JspFragment getJspBody()
protected JspContext getJspContext()
public static final JspTag findAncestorWithClass(JspTag from, java.lang.Class<?> klass)
使用自定义标签的过程如下
(1)浏览器访问JSP页面资源。
(2)Tomcat将JSP页面翻译成Servlet --> 编译该Servlet --> 构造类对象 --> 调用_jspService()方法。
(3)检查JSP文件的taglib指令,检查是否存在相应的tld文件,如果没有会报错。
(4)根据JSP页面中的标签名<easy:firstTag>在tld文件中找到相应的<tag>标签,并定位到标签处理器如下
<tag>
<name>firstTag</name>
<tag-class>app06a.MyFirstTag</tag-class>
<body-content>empty</body-content>
</tag>
(5)构造标签处理器app06a.MyFirstTag对象,然后调用标签处理器中的相应方法(将标签处理器的声明周期)
简单标签器的生命周期(即执行过程)如下: setJspContext(jspContext)和doTag()方法时一定会被JSP容器调用的
(1)JSP容器调用简单标签处理器的无参构造器并创建它的实例,因此简单标签处理器必须有无参构造器。
(2)JSP容器调用setJspContext(jspContext)方法,同时传入JspContext对象,该对象中最重要的方法是getOut()方法,其能够返回JspWriter对象,通过JspWriter就可以把相应返回前端了。通常情况下,要把传入的JspContext赋值给类的成员变量方便以后使用。
public void setJspContext(JspContext jspContext)
(3)如果标签处理器的定制标签嵌套再另一个自定义标签中,JSP容器就会调用setParent(jspTag)方法
public void setParent(JspTag parent)
(4)JSP容器调用该标签中所定义的每个属性的setter方法
(5)如果需要处理页面内容,JSP容器还会调用接口SimpleTag的setJspBody(jspBody)方法,把由JspFragment封装的页面内容传过来。如果没有页面内容则不会调用该方法。
public void setJspBody(JspFragment jspBody)
(6)JSP容器调用doTag()方法,所有变量在doTag方法返回时进行同步。doTag()方法只会执行一次,业务逻辑、遍历及页面内容操作都是在这里实现。
创建自定义标签的三步骤:
第一步:编写标签处理器,标签处理器就是一个实现了标签接口的Java类。在编写标签处理器时需要servlet-api.jar和jsp-api.jar这两个文件,不过Tomcat自带了,可以在Tomcat的lib目录下找到。
第二步:在标签库描述器中注册标签。标签库描述器是以.tld结尾的XML文件,该文件必须放在WEB-INF目录下(避免浏览器直接访问)。
第三步:使用自定义标签。需要用到<%@ taglib uri="uri" prefix="prefix" %>指令,其uri属性时标签库描述器的绝对路径或者相对路径,如果使用jar包中的标签库,就必须使用绝对路径了。
实例一
编写简单标签处理器
package app06a.customTag; import java.io.IOException; import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag; public class MyFirstTag implements SimpleTag { // 简单标签处理器必须有无参构造器,此处使用默认的无参构造器
JspContext jspContext; @Override
public void doTag() throws JspException, IOException { // JSP容器一定会调用该方法
System.out.println("doTag");
JspWriter out = jspContext.getOut();
out.println("This is my first tag.");
} @Override
public JspTag getParent() {
System.out.println("getparent");
return null;
} @Override
public void setJspBody(JspFragment jspFragment) { // 如果需要处理页面内容,JSP容器会调用该方法,且在调用doTag()方法之前
System.out.println("setJspBody"); } @Override
public void setJspContext(JspContext jspContext) { // JSP容器一定会调用该方法, 且首先调用该方法
this.jspContext = jspContext;
System.out.println("setJspContext");
} @Override
public void setParent(JspTag arg0) { // 如果自定义标签被另一个自定义标签所嵌套时,JSP容器调用该方法,且在调用doTag()方法之前
System.out.println("setParent");
}
}
编写标签库处理文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
<taglib>
<description>Simple tag example</description>
<tlib-version>1.0</tlib-version>
<jsp-version>1.0</jsp-version>
<short-name>My First taglib Example</short-name>
<tag>
<name>firstTag</name>
<tag-class>app06a.customTag.MyFirstTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
JSP页面中使用自定义标签
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/firstTag.tld" prefix="easy" %> <%-- 引入自定义标签描述库文件 --%> <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test my first tag</title>
</head>
<body>
Hello <br />
<easy:firstTag></easy:firstTag> <!-- 使用自定义标签 -->
</body>
</html>
测试结果

实例二 处理属性 继承类SimpletagSupport
编写简单标签处理器
package app06a.customTag; import java.io.IOException;
import java.util.StringTokenizer; import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport; public class DataFormatterTag extends SimpleTagSupport {
private String header;
private String items; public void setHeader(String header) { //JSP容器调用,并且在调用doTag()之前
this.header = header;
}
public void setItems(String items) {
this.items = items;
} @Override
public void doTag() throws IOException, JspException { // JSP容器调用,
JspContext jspContext = getJspContext();
JspWriter out = jspContext.getOut();
out.println("<table style='border:1px solid green'>");
out.println("<tr><td><span style='font-weight:bold'>" + header + "</span></td><tr>");
StringTokenizer tonkenizer = new StringTokenizer(items, ",");
while (tonkenizer.hasMoreTokens()) {
String token = tonkenizer.nextToken();
out.println("<tr><td>" + token + "</td></tr>");
}
out.println("</table>");
}
}
编写标签库处理文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
<taglib>
<description>Simple tag example</description>
<tlib-version>1.0</tlib-version>
<jsp-version>1.0</jsp-version>
<short-name>My First taglib Example</short-name> <tag>
<name>firstTag</name>
<tag-class>app06a.customTag.MyFirstTag</tag-class>
<body-content>empty</body-content>
</tag> <tag>
<name>dataFormatter</name>
<tag-class>app06a.customTag.DataFormatterTag</tag-class>
<body-content>empty</body-content>
<attribute> <!-- 属性 -->
<name>header</name>
<required>true</required>
</attribute>
<attribute>
<name>items</name>
<required>true</required>
</attribute>
</tag>
</taglib>
JSP页面中使用自定义标签
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/firstTag.tld" prefix="easy" %> <%-- 指定标签库描述文件 --%> <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Testing DataFormatterTag</title>
</head>
<body>
<easy:dataFormatter header="States" items="Alabama,Alaska,Georgia,Florida" /> <!-- 该标签中有两个属性 -->
<br />
<easy:dataFormatter header="Country" >
<jsp:attribute name="items"> <!-- 使用JSP动作给标签中的属性赋值 -->
IS,UK,Canada,Korea
</jsp:attribute>
</easy:dataFormatter>
</body>
</html>
测试

实例三 访问标签内容
在SimpleTag中,可以通过JSP容器传入的JspFragment对象来访问标签内容。JSP片段的定义不能包含脚本或者脚本表达式,只能是文本模板或者JSP标准节点。
JspFragment类中有两个方法
public abstract JspContext getJspContext() // 返回这个JspFragment关联的JspContext对象
public abstract void invoke(java.io.Writer out) throws JspException, java.io.IOException
// 执行标签的内容,然后通过指定的Writer对象将其直接输出,
// 如果把null传入invoke()方法中,那么这个Writer将会被JspFragment关联的JspContext对象中的getOut()方法返回的JspWriter对象所接管。
编写简单标签处理器
package app06a.customTag; import java.io.IOException; import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport; public class SelectElementTag extends SimpleTagSupport {
private String[] countries = {"Australia", "Brazil", "China", "Japan" }; @Override
public void doTag() throws IOException, JspException {
JspContext jspContext = getJspContext();
JspWriter out = jspContext.getOut();
JspFragment fragment = getJspBody(); out.println("<select>");
for (int i = 0; i < 4; i++) {
jspContext.setAttribute("value", countries[i]);
jspContext.setAttribute("text", countries[i]);
fragment.invoke(null);
}
out.println("</select>");
}
}
编写标签库处理文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" > <taglib>
<description>Simple tag example</description>
<tlib-version>1.0</tlib-version>
<jsp-version>1.0</jsp-version>
<short-name>My First Taglib Example</short-name> <tag>
<name>select</name>
<tag-class>app06a.customTag.SelectElementTag</tag-class>
<body-content>scriptless</body-content>
</tag>
</taglib>
JSP页面中使用自定义标签
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/mytags.tld" prefix="easy" %> <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Testing SelectElementFormatTag</title>
</head>
<body>
<easy:select>
<option value="${value }">${text }</option> <!-- 使用EL表达式 -->
</easy:select>
</body>
</html>
测试结果


发布自定义标签
在tld文件中添加<uri>元素
将自定义的标签处理器和标签库描述文件打包到JAR包中
使用时,将JAR包放到应用的WEB/lib目录下,在使用的时候,任何使用自定义标签的JSP页面都要使用这个标签库描述器中定义的uri

可以将整个应用打包,使用时放到应用的WEB/lib目录下



JSP自定义标签(标签处理器 tld文件)的更多相关文章
- Jsp 自定义tag标签
1转自:https://blog.csdn.net/yusimiao/article/details/46835617 Jsp自定义tag标签 自定义tag标签的好处 程序员可以自定一些特定功能的标记 ...
- Jsp自定义标签,配置tld文件
Program:Jsp自定义标签,.tld文件的配置 1 <?xml version="1.0" encoding="UTF-8" ?> 2 3 & ...
- JSP自定义简单标签入门之带有属性
上面写的那个简单标签来控制页面中标签内容的重复次数是固定的,这就是权限"写死了",这是非常不好的行为,因为其灵活性太差.所以下面就介绍一种使用属性来控制标签内容输出次数的方法. 准 ...
- JSP自定义业务标签
自定义标签: package cn.hv.tag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; ...
- 学会怎样使用Jsp 内置标签、jstl标签库及自定义标签
学习jsp不得不学习jsp标签,一般来说,对于一个jsp开发者,可以理解为jsp页面中出现的java代码越少,对jsp的掌握就越好,而替换掉java代码的重要方式就是使用jsp标签. jsp标签的分 ...
- Java jsp 自定义标签
1 自定义标签 1.1 引入 需求: 向浏览器输出当前客户的IP地址 (只能使用jsp标签) 1.2 第一个自定义标签开发步骤 1)编写一个普通的java类,继承SimpleTagSupport类,叫 ...
- [JSP]自定义标签库taglib
自定义标签的步骤 自定义标签的步骤大概有三步: 1.继承javax.servlet.jsp.tagext.*下提供的几个标签类,如Tag.TagSupport.BodyTagSupport.Simpl ...
- 讲解JSP自定义标签
一.基本概念 1.标签(Tag) 标签是一种XML元素,通过标签可以使JSP网页变得简洁并且易于维护,还可以方便地实现同一个JSP文件支持多种语言版本.由于标签是XML元素,所以它的名称和属性都是大小 ...
- javaweb学习总结(二十六)——jsp简单标签标签库开发(二)
一.JspFragment类介绍 javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段, ...
随机推荐
- soap 简单调用其他系统的函数
<?xml version ='1.0' encoding ='UTF-8' ?> <definitions name='自定义名称' targetNamespace='目标命名空间 ...
- python遇到的错误
今天学习文件遇到这个错误. 这是在 text_files\vvvv.txt 之间加一个\ 就可以了,变成 text_files\\vvvv.txt,运行成功
- Netty 能做什么
作为一个学Java的,如果没有研究过Netty,那么你对Java语言的使用和理解仅仅停留在表面水平,会点SSH,写几个MVC,访问数据库和缓存,这些只是初等Java程序员干的事.如果你要进阶,想了解J ...
- Sublime Text使用中的一些心得
Sublime Text3是每个web前端程序员的必备神器,其中有许多便利的功能及插件.下面列出一些在开发中比较实用的快捷操作,可以极大地提高代码的编写速度及效率. l 在文档中输入代码,即使忘记保 ...
- DIV实现垂直居中的几种方法
说道垂直居中,我们首先想到的是vertical-align属性,但是许多时候该属性并不起作用.例如,下面的样式并不能达到内容垂直居中显示 div { width:200px; height:300px ...
- EF CodeFirst学习笔记003--如何创建表
参考: http://www.cnblogs.com/Wayou/archive/2012/09/20/EF_CodeFirst.html webconfig中修改: <connectionSt ...
- 我的一次rsync+inotify本地数据同步示例
环境: web工作目录:/var/www/mydafuhao git仓库目录: /var/www/mydafuhao.git/mydafuhao 需求:inotify监控git仓库目录,发现有版本更新 ...
- ftp删除目录和文件,目录下有文件删除提示【550 Remove directory operation failed.】
注意:目录下有文件,直接删除目录会失败,提示550 Remove directory operation failed. 必须先将目录下的文件都删除,才能删除目录 ftp命令行: ftp删除目 ...
- git config --global user.email
加上这个就ok
- POJ-2251.DungeonMaster(三维BFS)
做题时需要注意,爬楼有向上和向下爬之分... 本题大意:输入 l, r, c, 分别代表地牢的楼层数和每层地牢的长和宽,地牢由rock and point and source and key组成,你 ...