Jsp自訂標籤實現

來源:互聯網
上載者:User

通過自訂標籤顯示日期為例

(一) 沒有本文的標籤實現

       (1):定義標籤處理類

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類 實現的介面是Tag。 如果有本文的標籤類繼承的是BodyTagSupport類 實現的介面是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 頁面動態引用

<%@ 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>

注意:動態引用和靜態引用的區別。

為了進行靜態引用,首先必須將下面的項加入到 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 值相匹配。

在進行標記庫的靜態引用時,JSP 聲明必須查詢 web.xml 檔案以執行庫查詢。這意味著如果移動或者重新命名了庫,或者希望在 web.xml 檔案中加入更多的庫,就必須停止伺服器、更新 web.xml 檔案、然後重新啟動伺服器。動態方法讓 JSP 頁直接指向 TLD 位置,因而是在解釋 JSP 頁面時進行處理。

 

(二)  沒有本文的但帶有屬性的標籤實現

 (1):定義標籤處理類

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類 實現的介面是Tag。 如果有本文的標籤類繼承的是BodyTagSupport類 實現的介面是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;
 }
 
 //必須實現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 頁面動態引用

<%@ 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>

 (三) 有本文的且帶有屬性的標籤實現

(1):定義標籤處理類

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;
 }

 // 必須實現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 頁面動態引用

<%@ 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>

效果圖:

 

執行順序

doStartTag()->setBodyContent()->doInitBody()->doAfterTag()->doEndTag()
如果doStartTag()返回的是EVAL_BODY_INCLUDE執行doAfterTag()方法,
如果它返回SKIP_BODY就執行doEndTag()方法。
setBodyContent()方法用於設定標籤體內容,如果在計算BodyContent時需要進行一些初始化工作,
則在doInitBody()方法中完成。標籤體內容執行完後,會調用doAfterBody()方法
在doAfterTag()方法中返回EVAL_BODY_AGAIN來重複執行doAfterTag()方法
返回SKIP_BODY值則執行doEndTag()方法。
在doEndTag()方法中返回EVAL_PAGE值,則執行此標籤的後的其它代碼,
返回SKIP_PAGE則不執行此頁面的其它代碼。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.