淺談JSP自定義標簽實現(xiàn)過程
(一) 沒有正文的JSP自定義標簽實現(xiàn)
(1):定義JSP自定義標簽處理類
- import java.io.IOException;
- import java.util.Date;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.jsp.JspException;
- import javax.servlet.jsp.JspWriter;
- import javax.servlet.jsp.tagext.Tag;
- import javax.servlet.jsp.tagext.TagSupport;
- //無正文標簽類繼承的是TagSupport類 實現(xiàn)的接口是Tag。 如果有正文的標簽類繼承的是BodyTagSupport類 實現(xiàn)的接口是BodyTag
- public class DateTagNoBody extends TagSupport {
- @Override
- public int doStartTag() throws JspException {
- HttpServletRequest request;
- // 是TagSupport類中定義的一個屬性,它是javax.servlet.jsp.PageContext的對象
- request = (HttpServletRequest) pageContext.getRequest();
- java.text.SimpleDateFormat formater = new java.text.SimpleDateFormat("yyyy-MM-dd");
- String date = formater.format(new Date());
- JspWriter out = pageContext.getOut();
- try {
- out.print(date);
- } catch (IOException e) {
- e.printStackTrace();
- }
- // doStartTag() 方法返回 SKIP_BODY 。當然其原因是我們的簡單日期標記沒有正文。
- return Tag.SKIP_BODY;
- }
- }
(2) 定義tld文件
- <?xml version="1.0" encoding="UTF-8"?>
- <taglib>
- <tlibversion>1.0</tlibversion>
- <jspversion>1.1</jspversion>
- <tag>
- <name>displayDate</name>
- <tagclass>cn.com.chenlly.tag.DateTagNoBody</tagclass>
- <bodycontent>empty</bodycontent>
- </tag>
- </taglib>
(3) JSP頁面動態(tài)引用
- <%@ page language="java" pageEncoding="UTF-8"%>
- <%@ taglib uri="/WEB-INF/datetag.tld" prefix="c"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- </head>
- <body>
- <c:displayDate/>
- </body>
- </html>
注意:動態(tài)引用和靜態(tài)引用的區(qū)別。
為了進行靜態(tài)引用,首先必須將下面的項加入到web.xml 文件中:
- <?xml version="1.0" encoding="ISO-8859-1" ?>
- <Web-app>
- <taglib>
- <taglib-uri>myTags</taglib-uri>
- <taglib-location>/WEB-INF/lib/DateTagLib.tld</taglib-location>
- </taglib>
- </Web-app>
然后,將JSP 聲明加入到所有需要使用自定義標記庫的頁面中:
- <%@ taglib uri="myTags" prefix="c" %>
指定的uri 屬性與在web.xml 文件中指定的taglib-uri 值相匹配。
在進行標記庫的靜態(tài)引用時,JSP 聲明必須查詢 web.xml 文件以執(zhí)行庫查詢。這意味著如果移動或者重命名了庫,或者希望在 web.xml 文件中加入更多的庫,就必須停止服務器、更新 web.xml 文件、然后重新啟動服務器。動態(tài)方法讓JSP頁直接指向 TLD 位置,因而是在解釋JSP頁面時進行處理。
(二) 沒有正文的但帶有屬性的JSP自定義標簽標簽實現(xiàn)
(1):定義JSP自定義標簽處理類
- import java.io.IOException;
- import java.util.Date;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.jsp.JspException;
- import javax.servlet.jsp.JspWriter;
- import javax.servlet.jsp.tagext.Tag;
- import javax.servlet.jsp.tagext.TagSupport;
- //無正文標簽類繼承的是TagSupport類 實現(xiàn)的接口是Tag。 如果有正文的標簽類繼承的是BodyTagSupport類 實現(xiàn)的接口是BodyTag
- public class DateTagNoBody extends TagSupport {
- private String pattern;
- @Override
- public int doStartTag() throws JspException {
- HttpServletRequest request;
- // 是TagSupport類中定義的一個屬性,它是javax.servlet.jsp.PageContext的對象
- request = (HttpServletRequest) pageContext.getRequest();
- java.text.SimpleDateFormat formater = new java.text.SimpleDateFormat(pattern);
- String date = formater.format(new Date());
- JspWriter out = pageContext.getOut();
- try {
- out.print(date);
- } catch (IOException e) {
- e.printStackTrace();
- }
- // doStartTag() 方法返回 SKIP_BODY 。當然其原因是我們的簡單日期標記沒有正文。
- return Tag.SKIP_BODY;
- }
- //必須實現(xiàn)setXX()方法
- public void setPattern(String pattern){
- this.pattern = pattern;
- }
- }
(2) 定義tld文件
- <?xml version="1.0" encoding="UTF-8"?>
- <taglib>
- <tlibversion>1.0</tlibversion>
- <jspversion>1.1</jspversion>
- <tag>
- <name>displayDate</name>
- <tagclass>cn.com.chenlly.tag.DateTagNoBody</tagclass>
- <bodycontent>empty</bodycontent>
- <!-- 定義屬性 -->
- <attribute>
- <name>pattern</name> <!-- 屬性名字 -->
- <type>String</type> <!-- 屬性類型 -->
- <requried>false</requried> <!-- 是否必須 -->
- <rtexprvale>false</rtexprvale> <!-- 表示是否可以使用JSP表達式 -->
- </attribute>
- </tag>
- </taglib>
(3)JSP頁面動態(tài)引用
- <%@ page language="java" pageEncoding="UTF-8"%>
- <%@ taglib uri="/WEB-INF/datetag.tld" prefix="c"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- </head>
- <body>
- <c:displayDate pattern='yyyy-MM-dd'/>
- </br>
- <c:displayDate pattern='MM/dd HH:mm:ss'/>
- </body>
- </html>
(三) 有正文的且?guī)в袑傩缘腏SP自定義標簽實現(xiàn)
(1):定義JSP自定義標簽處理類
- import java.io.IOException;
- import java.util.Date;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.jsp.JspException;
- import javax.servlet.jsp.JspWriter;
- import javax.servlet.jsp.tagext.BodyContent;
- import javax.servlet.jsp.tagext.BodyTagSupport;
- public class BodyTag extends BodyTagSupport {
- private int count;
- private HttpServletRequest reqeust;
- private JspWriter out;
- public void init() {
- reqeust = (HttpServletRequest) pageContext.getRequest();
- out = pageContext.getOut();
- }
- @Override
- public int doStartTag() throws JspException {
- init();
- return this.EVAL_BODY_INCLUDE;
- }
- //設置當前標簽體
- @Override
- public void setBodyContent(BodyContent bodyContent) {
- this.bodyContent = bodyContent;
- System.out.println("setBodyContent...");
- }
- //需要初始化bodyContent
- @Override
- public void doInitBody() throws JspException {
- System.out.println("init.....");
- }
- @Override
- public int doAfterBody() throws JspException {
- if (count >= 1) {
- try {
- out.println(count);
- out.println("<Br>");
- } catch (IOException e) {
- e.printStackTrace();
- }
- count --;
- return this.EVAL_BODY_AGAIN;
- } else {
- return this.SKIP_BODY;
- }
- }
- @Override
- public int doEndTag() throws JspException {
- java.text.SimpleDateFormat formater = new java.text.SimpleDateFormat(
- "yyyy-MM-dd");
- String date = formater.format(new Date());
- try {
- out.print(date);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return this.EVAL_PAGE;
- }
- // 必須實現(xiàn)setXX()方法
- public void setCount(int count) {
- this.count = count;
- }
- }
(2) 定義tld文件
- <?xml version="1.0" encoding="UTF-8"?>
- <taglib>
- <tlibversion>1.0</tlibversion>
- <jspversion>1.1</jspversion>
- <tag>
- <name>iterator</name>
- <tagclass>cn.com.chenlly.tag.BodyTag</tagclass>
- <bodycontent>jsp</bodycontent>
- <!-- 定義屬性 -->
- <attribute>
- <name>count</name> <!-- 屬性名字 -->
- <type>int</type> <!-- 屬性類型 -->
- <requried>false</requried> <!-- 是否必須 -->
- <rtexprvale>false</rtexprvale> <!-- 表示是否可以使用JSP表達式 -->
- </attribute>
- </tag>
- </taglib>
(3) jsp 頁面動態(tài)引用
- <%@ page language="java" pageEncoding="UTF-8"%>
- <%@ taglib uri="/WEB-INF/bodytag.tld" prefix="c"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- </head>
- <body>
- <c:iterator count="10">HelloWorld!</c:iterator>
- <%
- out.println("Bye Bye");
- %>
- </body>
- </html>
效果圖:

執(zhí)行順序
doStartTag()->setBodyContent()->doInitBody()->doAfterTag()->doEndTag()
如果doStartTag()返回的是EVAL_BODY_INCLUDE執(zhí)行doAfterTag()方法,
如果它返回SKIP_BODY就執(zhí)行doEndTag()方法。
setBodyContent()方法用于設置標簽體內容,如果在計算BodyContent時需要進行一些初始化工作,
則在doInitBody()方法中完成。標簽體內容執(zhí)行完后,會調用doAfterBody()方法
在doAfterTag()方法中返回EVAL_BODY_AGAIN來重復執(zhí)行doAfterTag()方法
返回SKIP_BODY值則執(zhí)行doEndTag()方法。
在doEndTag()方法中返回EVAL_PAGE值,則執(zhí)行此標簽的后的其它代碼,
返回SKIP_PAGE則不執(zhí)行此頁面的其它代碼。
【編輯推薦】