步骤:
1.编写一个实现tag接口的java类
2.在tld文件中对标签处理器类进行描述(路径:WEB—INF目录下;范例路径:tomcat/webapps/examples)
3.在jsp页面中导入自定义标签
运行原理:
浏览器向web服务器发出请求,服务器调用xxx.jsp,jsp中有一段代码是一自定义标签,服务器执行到这段代码时,首先实例化标签对应的标签处理器类,然后标签调用这个类,这个类实现了Tag接口。首先,调用setPageContext方法,把pageContext对象传递给标签处理器类;其次,看标签是否有父标签,如果有父标签,则把父标签作为一个对象,调用setParent方法传递给标签处理器类,如果没有,则传一个null;经过上述两个步骤,标签的初始化工作已完成,接下来服务器开始执行标签,这时遇到标签的开始标签,就调用tarttdoSag方法;如果标签有标签体,这时服务器一般会执行标签体;服务器遇到jsp页面结束标签,则调用标签处理器类的doEndTag方法;整个标签执行完后,服务器一般情况下会调用release()方法,释放标签工作所占用的资源。服务器介质再执行标签余下的jsp页面。
案例:使用标签输出客户机IP
1.编写一个实现tag接口的java类
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
//标签处理器类
public class ViewIPTag extends TagSupport {
@Override
public int doStartTag() throws JspException {
//request可以通过pageContext获取,标签的调用是由服务器来调用,
//setPageContext(PageContext pc)方法也是由服务器调用,
//服务器会先调用上述方法,把pageContext传递进来,再调用标签
HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest();
JspWriter out = this.pageContext.getOut();
String ip = request.getRemoteAddr();
//不能抛异常,因为覆盖的是父类的方法,只能抓
try {
out.print(ip);
} catch (IOException e) {
//不能打印,这个标签由JSP调用,出问题了要通知调用者
//要转成运行时异常抛出去
//e.printStackTrace();
throw new RuntimeException(e);
}
return super.doStartTag();
}
}
2.在tld文件中对标签处理器类进行描述(路径:WEB—INF目录下;范例路径:tomcat/webapps/examples)
<?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">
<description>A tag library exercising SimpleTag handlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>guigu</short-name>
<uri>/guigu</uri>
<tag>
<name>viewIP</name>
<tag-class>come.guigu.web.tag.ViewIPTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
3.在jsp页面中导入自定义标签
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/guigu" prefix="guigu" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP '1.jsp' starting page</title>
</head>
<body>
您的ip是:<guigu:viewIP/>
</body>
</html>
自定义标签功能扩展:
在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">
<description>A tag library exercising SimpleTag handlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>guigu</short-name>
<uri>/guigu</uri>
<tag>
<name>tagDemo1</name>
<tag-class>come.guigu.web.tag.TagDemo1</tag-class>
<body-content>JSP</body-content>
</tag>
<tag>
<name>tagDemo2</name>
<tag-class>come.guigu.web.tag.TagDemo2</tag-class>
<body-content>empty</body-content>
</tag>
<tag>
<name>tagDemo3</name>
<tag-class>come.guigu.web.tag.TagDemo3</tag-class>
<body-content>JSP</body-content>
</tag>
<tag>
<name>tagDemo4</name>
<tag-class>come.guigu.web.tag.TagDemo4</tag-class>
<body-content>JSP</body-content>
</tag>
</taglib>
1.控制jsp页面某一部分内容是否执行 设置标签体类型JSP
jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/guigu" prefix="guigu" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>使用标签控制页面内容(标签体)是否输出</title>
</head>
<body>
<guigu:tagDemo1>
aaaaaa
</guigu:tagDemo1>
</body>
</html>
能显示:
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
public class TagDemo1 extends TagSupport {
@Override
public int doStartTag() throws JspException {
return Tag.EVAL_BODY_INCLUDE;
}
}
不能显示:
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
public class TagDemo1 extends TagSupport {
@Override
public int doStartTag() throws JspException {
return Tag.SKIP_BODY;
}
}
2.控制整个jsp页面是否执行 ---->声明在页面的<!DOCTYPE 前 //设置标签体类型EMPTY
jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/guigu" prefix="guigu" %>
<guigu:tagDemo2/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用标签控制整个页面的输出</title>
</head>
<body>
This is my JSP page. <br>
</body>
</html>
能显示:
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
public class TagDemo2 extends TagSupport {
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return Tag.EVAL_PAGE;
}
}
不能显示:
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
public class TagDemo2 extends TagSupport {
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return Tag.SKIP_PAGE;
}
}
3.控制jsp页面内容重复执行 extendsTagSupport 设置标签体类型JSP
jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/guigu" prefix="guigu" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用标签控制标签体重复执行</title>
</head>
<body>
<guigu:tagDemo3>
This is my JSP page. <br>
</guigu:tagDemo3>
</body>
</html>
标签处理器类:
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.IterationTag;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
//控制标签体执行5次
public class TagDemo3 extends TagSupport {
int i = 5;
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
return Tag.EVAL_BODY_INCLUDE;
}
@Override
//方法在标签体执行完以后,结束标签之前执行
public int doAfterBody() throws JspException { //在IterationTag接口中的扩展
i--;
if(i>0) {
return IterationTag.EVAL_BODY_AGAIN;
} else {
return IterationTag.SKIP_BODY;
}
}
}
4.修改jsp页面内容输出。继承BodyTag接口的实现类BodyTagSupport //设置标签体类型JSP
编写的Java类实现了BodyTag接口,就可以控制doStartTag方法返回EVAL_BODY_BUFFERED(也就是说,BodyTag接口增加了一个新的常量)。
服务器拿到标签体之后,会将标签体作为一个对象,通过setBodyContent()方法传递给标签处理器类。
执行完标签体接下来就可以在doEndTag方法里拿到标签体,从而可以对标签体做出修改后再输出。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/guigu" prefix="guigu" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用标签修改JSP页面内容</title>
</head>
<body>
<guigu:tagDemo4>
aaaaa
</guigu:tagDemo4>
</body>
</html>
标签处理器类:
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
//修改标签体
public class TagDemo4 extends BodyTagSupport {
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
return BodyTag.EVAL_BODY_BUFFERED;
}
@Override
public int doEndTag() throws JspException {
BodyContent bc = this.getBodyContent(); //得到标签体
String content = bc.getString();
//把标签体的内容改为大写
content = content.toUpperCase();
try {
this.pageContext.getOut().write(content);
} catch (IOException e) {
throw new RuntimeException(e);
}
return Tag.EVAL_PAGE; // 余下的jsp页面还是要执行
}
}