天天看点

JavaWeb学习心得之JSP自定义标签

一、自定义标签的开发步骤

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>           

访问结果:

JavaWeb学习心得之JSP自定义标签

二、自定义标签执行流程

首先创建标签处理器类,然后按照顺序调用方法:

  1. setPageContext() 将JSP页面的PageContext对象传递给标签,标签可以通过PageContext对象与JSP页面进行通讯。
  2. setParent()将当前标签的父标签传递给当前标签处理器,如果没有,传递参数为null;
  3. doStartTag() web容器执行到自定义标签的开始标记时,执行该方法
  4. doEndTag() web容器执行完自定义标签后,执行该方法
  5. 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;

        }