天天看點

JavaWeb學習心得之自定義簡單标簽(一)

一、簡單标簽簡介

含義:實作SimpleTag接口的标簽稱為簡單标簽。

方法:

  • setJspContext:用于把JSP頁面的pageContext對象傳遞給标簽處理器對象
  • setParent:用于把父标簽處理器對象傳遞給目前标簽處理器對象
  • getParent:用于擷取目前标簽的父标簽對象
  • setJspBody:用于把标簽體的JspFragment對象傳遞給标簽處理器對象
  • doTag:用于完成所有标簽邏輯,包括輸出、疊代、修改标簽體内容等

方法執行順序:

  1. 調用setJspContext方法,将代表JSP頁面的pageContext對象傳遞給标簽處理器
  2. 調用setParent方法,将父标簽傳遞給目前标簽處理器對象,隻有父标簽存在時,才會調用該方法
  3. 調用setJspBody方法:把标簽體JspFragment對象傳進來
  4. 調用doTag方法,通過對JspFragment對象的操作,實作頁面邏輯

二、簡單标簽頁面邏輯 1.控制部分内容是否執行 SimpleTag

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
 * SimpleTagSupport類實作了SimpleTag接口
 * SampleTagDemo01類繼承SimpleTagSupport
 * @author hanxin
 *
 */
public class SimpleTagDemo01 extends SimpleTagSupport{
	/*
	 *  簡單标簽使用這個方法就可以完成所有的業務邏輯
	 *  重寫doTag方法,控制标簽體是否執行
	 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
	 */
	@Override
	public void doTag() throws JspException, IOException {
		//得到代表jsp标簽體的JspFragment
		JspFragment jspFragment = this.getJspBody();
		//得到jsp頁面的的PageContext對象
		//PageContext pageContext = (PageContext)jspFragment.getJspContext();
		//調用JspWriter将标簽體的内容輸出到浏覽器
		//jspFragment.invoke(pageContext.getOut());
		//調用invoke方法,表示輸出内容,否則将不輸出方法體内容
		jspFragment.invoke(null);
	}
	
}
           

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>SimpleTagLib</short-name>
       <!-- 
		        為自定義标簽庫設定一個uri,uri以/開頭,/後面的内容随便寫 ,
		        在Jsp頁面中引用标簽庫時,需要通過uri找到标簽庫
		        在Jsp頁面中就要這樣引入标簽庫:<%@taglib uri="/mySimpleTagLib" prefix="m"%>
		    -->
    <uri>/mySimpleTagLib</uri>
     <!--一個taglib(标簽庫)中包含多個自定義标簽,每一個自定義标簽使用一個tag标記來描述  -->
     <!-- 一個tag标記對應一個自定義标簽 -->
    <tag>
    	<description>SimpleTagDemo01</description>
    	<name>SimpleTagDemo01</name>
    	 <!-- 标簽對應的處理器類-->
    	<tag-class>com.hanxin.SimpleTagDemo01</tag-class>
    	  <!-- 
		        tld檔案中有四種标簽體類型 :empty  JSP  scriptless  tagdepentend  
			            在簡單标簽(SampleTag)中标簽體body-content的值隻允許是empty和scriptless,不允許設定成JSP,如果設定成JSP就會出現異常
			            在傳統标簽中标簽體body-content的值隻允許是empty和JSP
			            如果标簽體body-content的值設定成tagdepentend,那麼就表示标簽體裡面的内容是給标簽處理器類使用的,
			            例如:開發一個查詢使用者的sql标簽,此時标簽體重的SQL語句就是給SQL标簽的标簽處理器來使用的
			            <gacl:sql>SELECT * FROM USER</gacl:sql>
			            在這種情況下,sql标簽的<body-content>就要設定成tagdepentend,tagdepentend用得比較少,了解一下即可
	        -->
    	<body-content>scriptless</body-content>
    </tag>
</taglib>
           

jsp檔案

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="/mySimpleTagLib"  prefix="m"%>
<!DOCTYPE html>
<html >


<!-- 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>控制jsp頁面某一部分内容是否執行</title>
</head>

<body>
	<m:SimpleTagDemo01>控制jsp頁面某一部分内容是否執行</m:SimpleTagDemo01>
</body>
</html>
           

2.控制JSP頁面内容重複執行 SimpleTag類

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
 * SimpleTagSupport類實作了SimpleTag接口
 * SampleTagDemo02類繼承SimpleTagSupport
 * @author hanxin
 *
 */
public class SimpleTagDemo02 extends SimpleTagSupport{
	/*
	 *  簡單标簽使用這個方法就可以完成所有的業務邏輯
	 *  重寫doTag方法,控制标簽體是否執行
	 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
	 */
	@Override
	public void doTag() throws JspException, IOException {
		JspFragment jspFragment = this.getJspBody();
		/*
		 * 重複執行,隻需要重複調用invoke方法
		 */
		for(int i=0;i<10;i++){
			jspFragment.invoke(null);
		}
	}
	
}
           

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>SimpleTagLib</short-name>
       <!-- 
		        為自定義标簽庫設定一個uri,uri以/開頭,/後面的内容随便寫 ,
		        在Jsp頁面中引用标簽庫時,需要通過uri找到标簽庫
		        在Jsp頁面中就要這樣引入标簽庫:<%@taglib uri="/mySimpleTagLib" prefix="m"%>
		    -->
    <uri>/mySimpleTagLib</uri>
     <!--一個taglib(标簽庫)中包含多個自定義标簽,每一個自定義标簽使用一個tag标記來描述  -->
     <!-- 一個tag标記對應一個自定義标簽 -->
    <tag>
    	<description>SimpleTagDemo02</description>
    	<name>SimpleTagDemo02</name>
    	 <!-- 标簽對應的處理器類-->
    	<tag-class>com.hanxin.SimpleTagDemo02</tag-class>
    	  <!-- 
		        tld檔案中有四種标簽體類型 :empty  JSP  scriptless  tagdepentend  
			            在簡單标簽(SampleTag)中标簽體body-content的值隻允許是empty和scriptless,不允許設定成JSP,如果設定成JSP就會出現異常
			            在傳統标簽中标簽體body-content的值隻允許是empty和JSP
			            如果标簽體body-content的值設定成tagdepentend,那麼就表示标簽體裡面的内容是給标簽處理器類使用的,
			            例如:開發一個查詢使用者的sql标簽,此時标簽體重的SQL語句就是給SQL标簽的标簽處理器來使用的
			            <gacl:sql>SELECT * FROM USER</gacl:sql>
			            在這種情況下,sql标簽的<body-content>就要設定成tagdepentend,tagdepentend用得比較少,了解一下即可
	        -->
    	<body-content>scriptless</body-content>
    </tag>
</taglib>
           

jsp檔案

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="/mySimpleTagLib"  prefix="m"%>
<!DOCTYPE html>
<html >


<!-- 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>用簡單标簽控制标簽體執行</title>
</head>

<body>
	<m:SimpleTagDemo02>用簡單标簽控制标簽體執行<br></m:SimpleTagDemo02>
</body>
</html>
           

3.修改JSP頁面輸出 SimpleTag類

import java.io.IOException;
import java.io.StringWriter;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
 * SimpleTagSupport類實作了SimpleTag接口
 * SampleTagDemo03類繼承SimpleTagSupport
 * @author hanxin
 *
 */
public class SimpleTagDemo03 extends SimpleTagSupport{
	/*
	 *  簡單标簽使用這個方法就可以完成所有的業務邏輯
	 *  重寫doTag方法
	 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
	 */
	@Override
	public void doTag() throws JspException, IOException {
		JspFragment jspFragment = this.getJspBody();
		StringWriter sw = new StringWriter();
		//将标簽體的内容寫入到sw流中
		jspFragment.invoke(sw);
		//擷取sw流緩沖區的内容
		String content = sw.getBuffer().toString();
		content = content.toUpperCase();
		PageContext pageContext = (PageContext)jspFragment.getJspContext();
		//将修改後的content輸出到浏覽器中
		pageContext.getOut().write(content);
		
	}
	
}
           

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>SimpleTagLib</short-name>
       <!-- 
		        為自定義标簽庫設定一個uri,uri以/開頭,/後面的内容随便寫 ,
		        在Jsp頁面中引用标簽庫時,需要通過uri找到标簽庫
		        在Jsp頁面中就要這樣引入标簽庫:<%@taglib uri="/mySimpleTagLib" prefix="m"%>
		    -->
    <uri>/mySimpleTagLib</uri>
     <!--一個taglib(标簽庫)中包含多個自定義标簽,每一個自定義标簽使用一個tag标記來描述  -->
     <!-- 一個tag标記對應一個自定義标簽 -->
    <tag>
    	<description>SimpleTagDemo03</description>
    	<name>SimpleTagDemo03</name>
    	 <!-- 标簽對應的處理器類-->
    	<tag-class>com.hanxin.SimpleTagDemo03</tag-class>
    	  <!-- 
		        tld檔案中有四種标簽體類型 :empty  JSP  scriptless  tagdepentend  
			            在簡單标簽(SampleTag)中标簽體body-content的值隻允許是empty和scriptless,不允許設定成JSP,如果設定成JSP就會出現異常
			            在傳統标簽中标簽體body-content的值隻允許是empty和JSP
			            如果标簽體body-content的值設定成tagdepentend,那麼就表示标簽體裡面的内容是給标簽處理器類使用的,
			            例如:開發一個查詢使用者的sql标簽,此時标簽體重的SQL語句就是給SQL标簽的标簽處理器來使用的
			            <gacl:sql>SELECT * FROM USER</gacl:sql>
			            在這種情況下,sql标簽的<body-content>就要設定成tagdepentend,tagdepentend用得比較少,了解一下即可
	        -->
    	<body-content>scriptless</body-content>
    </tag>
</taglib>
           

jsp檔案

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="/mySimpleTagLib"  prefix="m"%>
<!DOCTYPE html>
<html >


<!-- 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>修改jsp頁面内容輸出</title>
</head>

<body>
	<m:SimpleTagDemo03>thing in java</m:SimpleTagDemo03>
</body>
</html>
           

4.控制JSP頁面是否執行 SimpleTag類

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
 * SimpleTagSupport類實作了SimpleTag接口
 * SampleTagDemo04類繼承SimpleTagSupport
 * @author hanxin
 *
 */
public class SimpleTagDemo04 extends SimpleTagSupport{
	/*
	 *  簡單标簽使用這個方法就可以完成所有的業務邏輯
	 *  重寫doTag方法
	 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
	 */
	@Override
	public void doTag() throws JspException, IOException {
		throw new SkipPageException();//抛出該異常頁面将不再繼續執行
	}
	
}
           

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>SimpleTagLib</short-name>
       <!-- 
		        為自定義标簽庫設定一個uri,uri以/開頭,/後面的内容随便寫 ,
		        在Jsp頁面中引用标簽庫時,需要通過uri找到标簽庫
		        在Jsp頁面中就要這樣引入标簽庫:<%@taglib uri="/mySimpleTagLib" prefix="m"%>
		    -->
    <uri>/mySimpleTagLib</uri>
     <!--一個taglib(标簽庫)中包含多個自定義标簽,每一個自定義标簽使用一個tag标記來描述  -->
     <!-- 一個tag标記對應一個自定義标簽 -->
    <tag>
    	<description>SimpleTagDemo04</description>
    	<name>SimpleTagDemo04</name>
    	 <!-- 标簽對應的處理器類-->
    	<tag-class>com.hanxin.SimpleTagDemo04</tag-class>
    	  <!-- 
		        tld檔案中有四種标簽體類型 :empty  JSP  scriptless  tagdepentend  
			            在簡單标簽(SampleTag)中标簽體body-content的值隻允許是empty和scriptless,不允許設定成JSP,如果設定成JSP就會出現異常
			            在傳統标簽中标簽體body-content的值隻允許是empty和JSP
			            如果标簽體body-content的值設定成tagdepentend,那麼就表示标簽體裡面的内容是給标簽處理器類使用的,
			            例如:開發一個查詢使用者的sql标簽,此時标簽體重的SQL語句就是給SQL标簽的标簽處理器來使用的
			            <gacl:sql>SELECT * FROM USER</gacl:sql>
			            在這種情況下,sql标簽的<body-content>就要設定成tagdepentend,tagdepentend用得比較少,了解一下即可
	        -->
    	<body-content>empty</body-content>
    </tag>
</taglib>
           

jsp檔案

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib uri="/mySimpleTagLib"  prefix="m"%>
<!DOCTYPE html>
<html >


<!-- 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>控制JSP是否繼續向下執行</title>
</head>

<body>
	<p>開始</p>
	<m:SimpleTagDemo04/>
	<p>結束</p>
</body>
</html>