一、自定义标签的开发步骤
1.编写Java类实现Tag接口(标签处理器类)
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
public class MyTag implements Tag{
//接收传递进来的PageContext对象
private PageContext pageContext;
@Override
public int doEndTag() throws JspException {
System.out.println("调用doEndTag方法");
return 0;
}
@Override
public int doStartTag() throws JspException {
System.out.println("调用doStartTag方法");
//获取Ip
HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
String ip = request.getRemoteAddr();
//获取输出流
JspWriter jw = pageContext.getOut();
//输出文本到浏览器
try {
jw.write(ip);
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
@Override
public Tag getParent() {
return null;
}
@Override
public void release() {
System.out.println("调用release方法");
}
@Override
public void setPageContext(PageContext pageContext) {
this.pageContext = pageContext;
}
@Override
public void setParent(Tag arg0) {
}
}
2.在WEB-INF中创建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用来添加对taglib(标签库)的描述 -->
<description>自定义标签库</description>
<!--taglib(标签库)的版本号 -->
<tlib-version>1.0</tlib-version>
<short-name>MyTagLib</short-name>
<!--
为自定义标签库设置一个uri,uri以/开头,/后面的内容随便写 ,
在Jsp页面中引用标签库时,需要通过uri找到标签库
在Jsp页面中就要这样引入标签库:<%@taglib uri="/myTag" prefix="m"%>
-->
<uri>/myTag</uri>
<!--一个taglib(标签库)中包含多个自定义标签,每一个自定义标签使用一个tag标记来描述 -->
<!-- 一个tag标记对应一个自定义标签 -->
<tag>
<description>自定义标签获取Ip</description>
<!--
为标签处理器类配一个标签名,在Jsp页面中使用标签时是通过标签名来找到要调用的标签处理器类的
通过getIp就能找到对应的com.hanxin.MyTag类
-->
<name>getIp</name>
<!-- 标签对应的处理器类-->
<tag-class>com.hanxin.MyTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
3.使用自定义标签
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/myTag" prefix="m"%>
<!DOCTYPE html>
<html lang="en">
<!-- Mirrored from www.zi-han.net/theme/hplus/login_v2.html by HTTrack Website Copier/3.x [XR&CO'2014], Wed, 20 Jan 2016 14:19:49 GMT -->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>test</title>
</head>
<body>
Java代码获取IP地址:
<%
String ip = request.getRemoteAddr();
out.write(ip);
%>
<br>
自定义标签获取IP地址
<m:getIp/>
</body>
</html>
访问结果:
二、自定义标签执行流程
首先创建标签处理器类,然后按照顺序调用方法:
- setPageContext() 将JSP页面的PageContext对象传递给标签,标签可以通过PageContext对象与JSP页面进行通讯。
- setParent()将当前标签的父标签传递给当前标签处理器,如果没有,传递参数为null;
- doStartTag() web容器执行到自定义标签的开始标记时,执行该方法
- doEndTag() web容器执行完自定义标签后,执行该方法
- release() 通常WEB容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务器,直至停止web应用时,web容器才会调用release方法。
查看JSP翻译成Servlet后的Java源代码(部分):
private boolean _jspx_meth_m_005fgetIp_005f0(javax.servlet.jsp.PageContext _jspx_page_context)
throws java.lang.Throwable {
javax.servlet.jsp.PageContext pageContext = _jspx_page_context;
javax.servlet.jsp.JspWriter out = _jspx_page_context.getOut();
// m:getIp
com.hanxin.MyTag _jspx_th_m_005fgetIp_005f0 = (com.hanxin.MyTag) _005fjspx_005ftagPool_005fm_005fgetIp_005fnobody
.get(com.hanxin.MyTag.class);
try {
_jspx_th_m_005fgetIp_005f0.setPageContext(_jspx_page_context);
_jspx_th_m_005fgetIp_005f0.setParent(null);
int _jspx_eval_m_005fgetIp_005f0 = _jspx_th_m_005fgetIp_005f0.doStartTag();
if (_jspx_th_m_005fgetIp_005f0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) {
return true;
}
} finally {
_005fjspx_005ftagPool_005fm_005fgetIp_005fnobody.reuse(_jspx_th_m_005fgetIp_005f0);
}
return false;
}
分析上述代码片段: 1.实例化getIp的处理器类com.hanxin.MyTag com.hanxin.MyTag _jspx_th_m_005fgetIp_005f0 =(com.hanxin.MyTag) _005fjspx_005ftagPool_005fm_005fgetIp_005fnobody.get(com.hanxin.MyTag.class);
2.调用setPageContext()方法 _jspx_th_m_005fgetIp_005f0.setPageContext(_jspx_page_context);
3.调用setParent()方法 _jspx_th_m_005fgetIp_005f0.setParent(null);
4.调用doStartTag()方法
int _jspx_eval_m_005fgetIp_005f0 = _jspx_th_m_005fgetIp_005f0.doStartTag();
5.调用doEndTag()方法
if (_jspx_th_m_005fgetIp_005f0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) {
return true;
}