1、自定义标签
JspTag接口:---------是所有自定义标签的父接口,Tag 接口和SimpeTag 是其直接子接口。
A: Tag接口
Tag接口是传统标签的父接口,定义了两个重要方法doStartTag()、doEndTag() ;
四个常量(EVAL_BODY_INCLUDE、SKIP_BODY、EVAL_PAGE、SKIP_PAGE )。
1、调用doStartTag() 方法执行后向Web容器返回常EVAL_BODY_INCLUDE、SKIP_BODY 。
返回EVAL_BODY_INCLUDE 则执行自定义标签的标签体;
返回SKIP_BODY则忽略自定义标签的标签体,直接解释执行自定义标签的结果标记。
2、调用doEndTag() 方法、执行后向Web容器返回常量EVAL_PAGE、SKIP_PAGE 。
返回EVAL_PAGE 则执行JSP页面位于结束标记后面的JSP代码;
返回SKIP_PAGE则忽略JSP页面中位于结束标记后面的所有内容,例如<jsp:forward> 标签。
IterationTag接口
IterationTag继承Tag接口,并增加了doAfterBody() 方法和EVAL_BODY_AGAIN 常量。
能通知Web容器是否重复执行标签体内容。当调用doAfterBody() 方法返回EVAL_BODY_AGAIN 时,
会重复执行标签,直到返回SKIP_BODY,Web容器才会处理标签的结束标记和调用doEndTag() 。
BodyTag接口
BodyTag接口继承自IterationTag 接口,增加2个方法setBodyContent()、doInitBody() 方法和EVAL_BODY_BUFFERED 常量。
当doStartTag()方法返回EVAL_BODY_BUFFERED 常量时,Web容器会创建专门用于捕获标签体运行结果的BodyContent 对象,
然后调用标签处理器的setBodyContent() 将BodyContent 对象传入标签处理器,Web容器将标签体的执行结果写入BodyContent 对象中。
在标签处理器的后续事件方法中,可以通过保存的BodyContent 的对象的引用来获取标签体的执行结果,
然后调用BodyContent对象特有的方法对BodyContent对象的内容进行修改和控制。
注:JSP API提供BodyTag接口的实现类BodyTagSupport 。
BodyTagSupport 类实现的BodyTagSupport类的doStartTag方法的返回值为EVAL_BODY_BUFFERED。
doAfterBody() 返回值为SKIP_BODY,doEndTag() 返回值为EVAL_PAGE 。
B: SimpleTag接口
SimpleTag接口为JSP2.0新增标签接口,在SimpleTag之中定义了一个用于处理标签逻辑的doTag()方法,
该方法在Web容器执行自定义标签时调用,而且只调用一次即完成传统标签的是否执行标签体、迭代标签等功能。
SimpleTagSupport类是SimpleTag接口的实现类。
简单自定义标签实例:
//自定义标签类
public class HtmlTag extends BodyTagSupport{
private static final long serialVersionUID = 1L;
private JspWriter out ;
private String name;
private String pass;
private int count ;
@Override
public int doStartTag() throws JspException {
count = 0;
out = this.pageContext.getOut();
try {
out.write("hello world ! "+name +" "+ pass+"<br/>");
} catch (Exception e) {
e.printStackTrace();
}
//多次调用时同一个对象,每次都会调用set/get方法复制属性
System.out.println(" this : "+ this);
return EVAL_BODY_INCLUDE;
}
@Override
public int doAfterBody() throws JspException {
if(count <5){
count ++;
return EVAL_BODY_AGAIN;
}
return SKIP_BODY;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
配置TLD文件:该文件可以放置于WEB-INF目录或者其子目录下面
<?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" version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>mm</short-name>
<uri>http://www.mm.org</uri>
<tag>
<name>html</name>
<tag-class>com.liusheng.tag.HtmlTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>name</name>
<required>true</required>
</attribute>
<attribute>
<name>pass</name>
<required>true</required>
</attribute>
</tag>
</taglib>
使用自定义标签
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="mm" uri="http://www.mm.org" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<mm:html name="liushegn" pass="12345">
1111
</mm:html>
<mm:html name="zhangsan" pass="34534">
2222
</mm:html>
</body>
</html>